#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
增强的HTTP服务器，提供静态文件服务和API端点
"""

import http.server
import socketserver
import webbrowser
import os
import sys
import json
import logging
import traceback
from pathlib import Path
from threading import Timer
from urllib.parse import urlparse, parse_qs
from datetime import datetime
from logging.handlers import RotatingFileHandler
from typing import Any, Dict, List, Optional

SKIP_STDOUT_RECONFIG = os.environ.get('SKIP_STDOUT_RECONFIG') == '1'


def configure_windows_console() -> None:
    """在Windows环境下配置控制台编码，避免影响测试捕获"""
    if sys.platform != 'win32':
        return
    if SKIP_STDOUT_RECONFIG:
        return

    import io

    try:
        if hasattr(sys.stdout, 'buffer'):
            sys.stdout.buffer.reconfigure(encoding='utf-8')
        if hasattr(sys.stderr, 'buffer'):
            sys.stderr.buffer.reconfigure(encoding='utf-8')
    except Exception:
        pass

    try:
        os.system('chcp 65001 >nul 2>&1')
    except Exception:
        pass


configure_windows_console()


# 导入Monitor相关模块
try:
    from monitor import N8nMonitor
    from config import DB_CONFIG, DEEPSEEK_API_KEY
    from enhanced_logging import setup_enhanced_logging, APILogger
    API_AVAILABLE = True
except ImportError:
    API_AVAILABLE = False
    print("[WARNING] 无法导入Monitor模块，API功能将不可用")


# ========================================
# 配置logging
# ========================================
def setup_logging():
    """配置日志系统"""
    # 创建logs目录
    if not os.path.exists('logs'):
        os.makedirs('logs')
    
    # 配置日志格式
    log_format = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    
    # 文件日志处理器（带轮转）
    file_handler = RotatingFileHandler(
        'logs/server.log',
        maxBytes=10*1024*1024,  # 10MB
        backupCount=5,
        encoding='utf-8'
    )
    file_handler.setLevel(logging.DEBUG)
    file_handler.setFormatter(log_format)
    
    # 控制台日志处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)  # 控制台显示INFO级别
    console_handler.setFormatter(log_format)
    
    # 配置root logger
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.DEBUG)
    root_logger.addHandler(file_handler)
    root_logger.addHandler(console_handler)
    
    # 如果增强logging可用，使用它
    if API_AVAILABLE:
        try:
            enhanced_loggers = setup_enhanced_logging('INFO')
            logger = logging.getLogger(__name__)
            logger.info("增强日志系统初始化完成")
            return logger, enhanced_loggers
        except Exception as e:
            logger = logging.getLogger(__name__)
            logger.warning(f"增强日志初始化失败: {e}，使用基础日志")
            return logger, None
    else:
        logger = logging.getLogger(__name__)
        logger.info("基础日志系统初始化完成")
        return logger, None


def _format_prompt_context(context: Optional[Dict[str, Any]]) -> str:
    if not context:
        return ""
    parts = []
    for key, value in context.items():
        try:
            parts.append(f"{key}={value}")
        except Exception:
            parts.append(f"{key}=<unserializable>")
    return " ".join(parts)


def sync_current_prompt(
    handler_cls: Any,
    new_prompt: Optional[str],
    logger: logging.Logger,
    source: str,
    context: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
    """同步最新提示词到处理器类并记录详细日志"""

    context_str = _format_prompt_context(context)
    context_suffix = f" {context_str}" if context_str else ""

    if new_prompt is None or len(str(new_prompt).strip()) == 0:
        logger.warning(f"[提示词同步] 来源={source} 收到为空的新提示词，忽略同步{context_suffix}")
        return {
            'changed': False,
            'old_length': len(getattr(handler_cls, 'current_prompt', '') or ''),
            'new_length': 0,
            'source': source,
            'context': context or {},
        }

    old_prompt = getattr(handler_cls, 'current_prompt', None)
    old_length = len(old_prompt) if old_prompt else 0
    new_length = len(new_prompt)

    if old_prompt == new_prompt:
        logger.info(
            f"[提示词同步] 来源={source} 新旧提示词一致，无需更新 旧长度={old_length} 新长度={new_length}{context_suffix}"
        )
        return {
            'changed': False,
            'old_length': old_length,
            'new_length': new_length,
            'source': source,
            'context': context or {},
        }

    handler_cls.current_prompt = new_prompt

    logger.info(
        f"[提示词同步] 来源={source} 同步提示词成功 旧长度={old_length} 新长度={new_length}{context_suffix}"
    )
    logger.debug(f"[提示词同步] 新提示词预览: {new_prompt[:200]}...")

    return {
        'changed': True,
        'old_length': old_length,
        'new_length': new_length,
        'source': source,
        'context': context or {},
    }


class EnhancedHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
    """增强的HTTP请求处理器，支持API端点"""

    monitor = None  # 类级别的monitor实例，所有请求共享
    logger = logging.getLogger('server')  # 类级别的logger
    current_prompt = None  # 类级别的当前提示词
    FEEDBACK_HISTORY_LIMIT = 3
    STATS_DB_ENV = 'REPLY_REASONABLE_STATS_DB'
    FEEDBACK_DB_ENV = 'USER_FEEDBACK_DB_PATH'
    
    @classmethod
    def load_saved_prompt(cls, category='reply_reasonable'):
        """加载保存的提示词"""
        try:
            import json
            prompt_file = f'data/{category}_prompt.json'
            
            if os.path.exists(prompt_file):
                with open(prompt_file, 'r', encoding='utf-8') as f:
                    prompt_data = json.load(f)
                    cls.current_prompt = prompt_data.get('prompt')
                    cls.logger.info(f"[初始化] 已加载保存的{category}提示词，长度: {len(cls.current_prompt) if cls.current_prompt else 0}")
                    return True
        except Exception as e:
            cls.logger.error(f"[初始化] 加载保存的提示词失败: {str(e)}")
        
        return False

    @classmethod
    def _resolve_statistics_db_path(cls) -> Path:
        env_path = os.environ.get(cls.STATS_DB_ENV)
        if env_path:
            db_path = Path(env_path)
        else:
            db_path = Path('data') / 'reply_reasonable_statistics.db'
        db_path.parent.mkdir(parents=True, exist_ok=True)
        return db_path

    @classmethod
    def _resolve_feedback_db_path(cls) -> Path:
        env_path = os.environ.get(cls.FEEDBACK_DB_ENV)
        if env_path:
            db_path = Path(env_path)
        else:
            db_path = Path('data') / 'user_feedback.db'
        db_path.parent.mkdir(parents=True, exist_ok=True)
        return db_path

    @classmethod
    def update_reply_statistics_with_feedback(
        cls,
        pair_id: int,
        new_evaluation: Dict[str, Any],
        logger: Optional[logging.Logger] = None,
    ) -> bool:
        import sqlite3

        active_logger = logger or logging.getLogger('server')
        stats_db_path = cls._resolve_statistics_db_path()

        if not stats_db_path.exists():
            active_logger.warning(
                "[回复统计] 统计数据库不存在，跳过更新 pair_id=%s 路径=%s",
                pair_id,
                stats_db_path,
            )
            return False

        conn = None
        try:
            conn = sqlite3.connect(str(stats_db_path))
            cursor = conn.cursor()
            cursor.execute(
                """
                SELECT id, statistics_data
                FROM reply_reasonable_statistics
                ORDER BY timestamp DESC
                LIMIT 1
                """
            )
            row = cursor.fetchone()

            if not row or not row[1]:
                active_logger.warning(
                    "[回复统计] 未找到统计记录，无法更新 pair_id=%s",
                    pair_id,
                )
                return False

            record_id, stats_json = row
            try:
                statistics = json.loads(stats_json)
            except json.JSONDecodeError as exc:
                active_logger.error(
                    "[回复统计] 统计数据解析失败 pair_id=%s 错误=%s",
                    pair_id,
                    exc,
                    exc_info=True,
                )
                return False

            evaluations = statistics.get('all_evaluations') or []
            target = next((item for item in evaluations if item.get('pair_id') == pair_id), None)

            if not target:
                active_logger.warning(
                    "[回复统计] 未找到pair_id=%s对应的评估记录，保持原状",
                    pair_id,
                )
                return False

            evaluation_payload = target.setdefault('evaluation', {})
            evaluation_payload.update(new_evaluation)
            evaluation_payload.setdefault('success', True)
            target['status'] = 'evaluated'
            now_iso = datetime.now().isoformat()
            target['updated_at'] = now_iso
            target['updated_from_feedback'] = True

            def _is_successful(item: Dict[str, Any]) -> bool:
                evaluation = item.get('evaluation', {})
                return bool(evaluation.get('success', False))

            evaluations_success = [item for item in evaluations if _is_successful(item)]
            evaluated_success = [
                item
                for item in evaluations_success
                if item.get('status') == 'evaluated'
            ]

            statistics['all_evaluations'] = evaluations
            statistics['timestamp'] = now_iso
            statistics['total_pairs'] = len(evaluations)
            statistics['evaluated_count'] = len(evaluated_success)
            statistics['reasonable_count'] = sum(
                1
                for item in evaluated_success
                if item.get('evaluation', {}).get('is_reasonable', False)
            )
            statistics['unreasonable_count'] = sum(
                1
                for item in evaluated_success
                if item.get('evaluation', {}).get('success', False)
                and not item.get('evaluation', {}).get('is_reasonable', False)
            )
            statistics['failed_count'] = statistics['total_pairs'] - len(evaluations_success)
            statistics['last_feedback_pair_id'] = pair_id
            statistics['updated_via_feedback'] = True

            updated_json = json.dumps(statistics, ensure_ascii=False)

            cursor.execute(
                """
                UPDATE reply_reasonable_statistics
                SET timestamp = ?, total_pairs = ?, evaluated_count = ?,
                    reasonable_count = ?, unreasonable_count = ?, failed_count = ?,
                    statistics_data = ?
                WHERE id = ?
                """,
                (
                    statistics['timestamp'],
                    statistics['total_pairs'],
                    statistics['evaluated_count'],
                    statistics['reasonable_count'],
                    statistics['unreasonable_count'],
                    statistics['failed_count'],
                    updated_json,
                    record_id,
                ),
            )
            conn.commit()

            active_logger.info(
                "[回复统计] 已根据用户反馈更新统计 pair_id=%s 合理=%s score=%s",
                pair_id,
                evaluation_payload.get('is_reasonable'),
                evaluation_payload.get('score'),
            )
            active_logger.info(
                "[回复统计] 更新后的统计数据: 合理=%s, 不合理=%s, 总数=%s",
                statistics['reasonable_count'],
                statistics['unreasonable_count'],
                statistics['total_pairs'],
            )
            print(f"[回复统计] ✅ 统计数据已更新到数据库")
            print(f"[回复统计]    - 合理回复数: {statistics['reasonable_count']}")
            print(f"[回复统计]    - 不合理回复数: {statistics['unreasonable_count']}")
            print(f"[回复统计]    - 总消息对数: {statistics['total_pairs']}")
            return True

        except Exception as exc:
            active_logger.error(
                "[回复统计] 更新统计失败 pair_id=%s 错误=%s",
                pair_id,
                exc,
                exc_info=True,
            )
            return False
        finally:
            if conn:
                conn.close()

    @classmethod
    def update_statistics_after_feedback(
        cls,
        pair_id: int,
        evaluation_payload: Dict[str, Any],
        logger: Optional[logging.Logger] = None,
    ) -> bool:
        """更新统计数据库（别名方法，调用update_reply_statistics_with_feedback）"""
        return cls.update_reply_statistics_with_feedback(
            pair_id=pair_id,
            new_evaluation=evaluation_payload,
            logger=logger
        )
    
    @classmethod
    def prepare_feedback_history(
        cls,
        history_records: List[Dict[str, Any]],
        limit: Optional[Any] = None,
        logger: Optional[logging.Logger] = None,
    ) -> Dict[str, Any]:
        """拆分评估历史，返回最新记录与其余历史记录"""

        active_logger = logger or logging.getLogger('server')

        def _normalize_limit(raw_limit: Optional[Any]) -> Optional[int]:
            if raw_limit is None:
                return cls.FEEDBACK_HISTORY_LIMIT
            if isinstance(raw_limit, str):
                if raw_limit.lower() == 'all':
                    return None
                try:
                    return max(int(raw_limit), 0)
                except ValueError:
                    active_logger.warning(
                        "[评估历史] 非法的limit参数=%s，回退到默认值=%s",
                        raw_limit,
                        cls.FEEDBACK_HISTORY_LIMIT,
                    )
                    return cls.FEEDBACK_HISTORY_LIMIT
            try:
                return max(int(raw_limit), 0)
            except (TypeError, ValueError):
                active_logger.warning(
                    "[评估历史] 无法解析limit参数=%s，回退到默认值=%s",
                    raw_limit,
                    cls.FEEDBACK_HISTORY_LIMIT,
                )
                return cls.FEEDBACK_HISTORY_LIMIT

        normalized_limit = _normalize_limit(limit)

        if not history_records:
            active_logger.info(
                "[评估历史] 没有历史记录，返回空结果 limit=%s",
                normalized_limit,
            )
            return {
                'latest_record': None,
                'history_records': [],
                'has_more_history': False,
                'applied_limit': normalized_limit,
            }

        sorted_history = sorted(
            history_records,
            key=lambda r: r.get('feedback_timestamp', ''),
            reverse=True,
        )
        latest_record = sorted_history[0]

        if normalized_limit is None or normalized_limit == 0:
            remaining_history = sorted_history[1:]
            has_more_history = False
        else:
            remaining_history = sorted_history[1: 1 + normalized_limit]
            has_more_history = len(sorted_history) > (1 + normalized_limit)

        active_logger.info(
            "[评估历史] 历史拆分完成 最新记录ID=%s 剩余记录数=%s 是否还有更多=%s limit=%s",
            latest_record.get('id'),
            len(remaining_history),
            has_more_history,
            normalized_limit,
        )

        return {
            'latest_record': latest_record,
            'history_records': remaining_history,
            'has_more_history': has_more_history,
            'applied_limit': normalized_limit,
        }
    
    def do_GET(self):
        """处理GET请求"""
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        
        print(f"[GET] {path}")
        
        # 处理API请求
        if path.startswith('/api/'):
            self.handle_api_request(path, parsed_path.query)
        else:
            # 处理静态文件请求
            super().do_GET()
    
    def do_POST(self):
        """处理POST请求"""
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        
        print(f"[POST] {path}")
        
        # 处理API POST请求
        if path.startswith('/api/'):
            self.handle_api_post_request(path)
        else:
            self.send_error(404, "Not Found")
    
    def handle_api_request(self, path, query_string):
        """处理API GET请求"""
        if not API_AVAILABLE:
            self.send_json_response({'error': 'API不可用'}, status_code=503)
            return
        
        query_params = parse_qs(query_string)
        
        try:
            if path == '/api/health':
                self.handle_health()
            elif path == '/api/batch-evaluate':
                self.handle_batch_evaluate(query_params)
            elif path == '/api/batch-evaluate-sse':
                print(f"[路由] 命中 SSE 端点: {path}")
                self.handle_batch_evaluate_sse(query_params)
            elif path == '/api/test-sse':
                print(f"[路由] 命中测试SSE端点: {path}")
                self.handle_test_sse()
            elif path == '/api/evaluation-statistics':
                self.handle_evaluation_statistics()
            elif path == '/api/mysql-statistics':
                self.handle_mysql_statistics()
            elif path == '/api/reply-reasonable-statistics':
                self.handle_reply_reasonable_statistics()
            elif path == '/api/get-feedback-history':
                self.handle_get_feedback_history(query_params)
            elif path == '/api/get-prompt':
                self.handle_get_prompt(query_params)
            elif path == '/api/candidate-messages':
                self.handle_candidate_messages(query_params)
            elif path == '/api/message-dates':
                self.handle_message_dates()
            else:
                self.send_error(404, "API端点不存在")
        except Exception as e:
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_api_post_request(self, path):
        """处理API POST请求"""
        if not API_AVAILABLE:
            print(f"[API] ❌ API不可用，路径: {path}")
            self.send_json_response({'error': 'API不可用'}, status_code=503)
            return
        
        try:
            # 读取请求体
            content_length = int(self.headers.get('Content-Length', 0))
            post_data = self.rfile.read(content_length)
            data = json.loads(post_data.decode('utf-8'))
            
            print(f"[API] 处理POST请求: {path}")
            print(f"[API] 请求数据大小: {content_length} 字节")
            
            if path == '/api/batch-evaluate':
                self.handle_batch_evaluate_post(data)
            elif path == '/api/evaluate-user-messages':
                self.handle_evaluate_user_messages_post(data)
            elif path == '/api/evaluate-reply-reasonable':
                self.handle_evaluate_reply_reasonable_post(data)
            elif path == '/api/save-feedback':
                self.handle_save_feedback_post(data)
            elif path == '/api/update-prompt':
                self.handle_update_prompt_post(data)
            elif path == '/api/export-evaluations':
                self.handle_export_evaluations_post(data)
            else:
                print(f"[API] ❌ 未知的API端点: {path}")
                self.send_error(404, "API端点不存在")
        except Exception as e:
            print(f"[API] ❌ 处理请求时出错: {str(e)}")
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_health(self):
        """健康检查"""
        self.send_json_response({
            'status': 'healthy',
            'api_available': API_AVAILABLE,
            'timestamp': datetime.now().isoformat()
        })
    
    def handle_batch_evaluate(self, query_params):
        """处理批量评估GET请求"""
        limit = int(query_params.get('limit', [50])[0])
        self.perform_batch_evaluation(limit)
    
    def handle_test_sse(self):
        """简单的SSE测试端点"""
        print("\n" + "="*60)
        print("🧪 [测试] SSE测试端点被调用")
        print("="*60)
        
        try:
            # 发送SSE响应头
            self.send_response(200)
            self.send_header('Content-Type', 'text/event-stream')
            self.send_header('Cache-Control', 'no-cache')
            self.send_header('Connection', 'keep-alive')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            
            print("✅ SSE响应头已发送")
            
            # 发送几个测试事件
            import time
            for i in range(5):
                message = f"data: {json.dumps({'count': i+1, 'message': f'测试消息 {i+1}'}, ensure_ascii=False)}\n\n"
                self.wfile.write(message.encode('utf-8'))
                self.wfile.flush()
                print(f"📤 发送测试消息 {i+1}")
                time.sleep(1)
            
            # 发送完成消息
            final_message = f"data: {json.dumps({'complete': True, 'message': '测试完成'}, ensure_ascii=False)}\n\n"
            self.wfile.write(final_message.encode('utf-8'))
            self.wfile.flush()
            print("✅ 测试完成")
            
        except Exception as e:
            print(f"❌ SSE测试失败: {str(e)}")
            import traceback
            traceback.print_exc()
    
    def handle_batch_evaluate_sse(self, query_params):
        """处理SSE批量评估请求"""
        print("\n" + "="*60)
        print("🚀 [重要] 收到SSE评估请求")
        print("="*60)
        
        self.logger.info("[批量评估SSE] 开始处理SSE请求")
        
        try:
            limit = int(query_params.get('limit', [50])[0])
            print(f"📊 消息条数限制: {limit}")
            
            # 设置SSE响应头
            self.send_sse_headers()
            
            # 立即发送一个测试事件以验证连接
            print("🔄 发送测试事件...")
            test_message = f"data: {json.dumps({'type': 'test', 'message': 'SSE连接成功'}, ensure_ascii=False)}\n\n"
            self.wfile.write(test_message.encode('utf-8'))
            self.wfile.flush()
            
            # 执行带进度推送的批量评估
            self.perform_batch_evaluation_with_sse(limit)
            
        except Exception as e:
            print(f"❌ SSE处理失败: {str(e)}")
            self.logger.error(f"[批量评估SSE] 处理失败: {str(e)}", exc_info=True)
    
    def perform_batch_evaluation_with_sse(self, limit, evaluate_type='all'):
        """执行带SSE进度推送的批量评估"""
        self.logger.info("=" * 80)
        self.logger.info("[批量评估SSE] ========== 开始执行SSE批量评估 ==========")
        self.logger.info(f"[批量评估SSE] 限制消息数: {limit}")
        self.logger.info("=" * 80)
        
        try:
            # 发送初始化事件
            self.logger.info("[SSE评估] ========== 开始SSE 评估流程 ==========")
            print("\n" + "="*60)
            print("🚀 开始实时评估流程 (SSE模式)")
            print("="*60)
            
            self.send_sse_event('init', {
                'message': '正在初始化评估系统...',
                'percent': 0
            })
            
            # 初始化monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[批量评估SSE] Monitor未初始化，正在初始化...")
                self.send_sse_event('progress', {
                    'message': '正在初始化数据库连接...',
                    'percent': 5
                })
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                self.logger.info("[批量评估SSE] Monitor初始化完成，连接数据库...")
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[批量评估SSE] 数据库连接失败")
                    self.send_sse_event('error', {
                        'message': '数据库连接失败',
                        'error': '无法连接到MySQL数据库'
                    })
                    return
                self.logger.info("[批量评估SSE] 数据库连接成功")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            # 发送进度：获取候选人列表
            self.send_sse_event('progress', {
                'message': '正在获取候选人列表...',
                'percent': 10
            })
            
            # 获取候选人列表
            self.logger.info("[批量评估SSE] 查询候选人列表...")
            query = """
            SELECT c.id, c.name, c.boss_uid, c.updated_at
            FROM candidates c
            WHERE c.updated_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
            GROUP BY c.id, c.name, c.boss_uid, c.updated_at
            ORDER BY c.updated_at DESC
            """
            monitor.cursor.execute(query)
            candidates = monitor.cursor.fetchall()
            self.logger.info(f"[批量评估SSE] 找到 {len(candidates)} 个候选人")
            
            # 发送进度：收集消息
            self.send_sse_event('progress', {
                'message': f'正在收集 {len(candidates)} 个候选人的消息...',
                'percent': 20,
                'total_candidates': len(candidates)
            })
            
            # 收集所有消息
            all_messages = []
            for idx, candidate in enumerate(candidates):
                candidate_id = candidate['id']
                candidate_name = candidate['name']
                
                # 更新进度
                progress = 20 + int((idx / len(candidates)) * 10)  # 20-30%
                self.send_sse_event('progress', {
                    'message': f'正在收集候选人 {candidate_name} 的消息...',
                    'percent': progress,
                    'current_candidate': idx + 1,
                    'total_candidates': len(candidates)
                })
                
                # 获取该候选人的消息
                msg_query = """
                SELECT id, content, created_at
                FROM messages
                WHERE candidate_id = %s AND sender = '我'
                ORDER BY created_at DESC
                LIMIT %s
                """
                monitor.cursor.execute(msg_query, (candidate_id, limit if limit > 0 else 1000))
                messages = monitor.cursor.fetchall()
                
                for msg in messages:
                    all_messages.append({
                        'id': msg['id'],
                        'content': msg['content'],
                        'candidate_id': candidate_id,
                        'candidate_name': candidate_name,
                        'created_at': str(msg['created_at'])
                    })
            
            self.logger.info(f"[批量评估SSE] 共收集到 {len(all_messages)} 条消息")
            
            # 如果有limit限制，只评估前N条
            if limit > 0:
                all_messages = sorted(all_messages, key=lambda x: x['created_at'], reverse=True)[:limit]
                self.logger.info(f"[批量评估SSE] 限制后消息数: {len(all_messages)}")
            
            # 发送进度：关键词筛选
            self.send_sse_event('progress', {
                'message': '正在进行关键词筛选...',
                'percent': 35,
                'total_messages': len(all_messages)
            })
            
            # 关键词筛选
            from config import SALARY_KEYWORDS, PHOTO_REQUEST_KEYWORDS
            
            def check_keywords(text, keywords):
                """检查文本是否包含关键词"""
                return any(keyword in text for keyword in keywords)
            
            relevant_messages = []
            for msg in all_messages:
                text = msg['content']
                is_salary = check_keywords(text, SALARY_KEYWORDS)
                is_photo = check_keywords(text, PHOTO_REQUEST_KEYWORDS)
                
                if is_salary or is_photo:
                    relevant_messages.append(msg)
            
            self.logger.info(f"[批量评估SSE] 关键词筛选完成 - 通过: {len(relevant_messages)}")
            
            # 如果没有需要评估的消息，直接返回
            if len(relevant_messages) == 0:
                self.logger.warning("[批量评估SSE] 没有找到需要评估的消息")
                self.send_sse_event('complete', {
                    'percent': 100,
                    'message': '没有找到需要评估的消息',
                    'success': True,
                    'total_candidates': len(candidates),
                    'total_messages': len(all_messages),
                    'evaluated_count': 0,
                    'failed_count': 0,
                    'all_evaluations': [],
                    'timestamp': datetime.now().isoformat()
                })
                return
            
            # 发送进度：开始AI评估
            self.send_sse_event('progress', {
                'message': f'开始AI评估 {len(relevant_messages)} 条消息...',
                'percent': 40,
                'messages_to_evaluate': len(relevant_messages)
            })
            
            # AI评估
            evaluations = []
            evaluated_count = 0
            failed_count = 0
            
            for i, msg in enumerate(relevant_messages):
                try:
                    # 计算进度（40-90%）
                    # 修复：使用(i+1)确保进度从第一个开始就更新
                    progress = 40 + int(((i + 1) / len(relevant_messages)) * 50)
                    
                    # 发送详细进度
                    self.send_sse_event('progress', {
                        'percent': progress,
                        'current': i + 1,
                        'total': len(relevant_messages),
                        'message': f'正在评估消息 ({i+1}/{len(relevant_messages)})',
                        'candidate': msg['candidate_name'],
                        'message_preview': msg['content'][:50] + '...' if len(msg['content']) > 50 else msg['content']
                    })
                    
                    # 添加延迟以确保SSE事件被正确发送
                    import time
                    time.sleep(0.1)  # 100ms延迟，确保浏览器能接收到事件
                    
                    self.logger.info(f"[批量评估SSE] [{i+1}/{len(relevant_messages)}] 评估消息 ID: {msg['id']}")
                    
                    # 调用AI评估
                    result = monitor.salary_analyzer.evaluator.evaluate_multi_criteria(msg['content'])
                    
                    # 构建评估数据
                    evaluation_data = {
                        'success': result.get('success', False),
                        'salary_score': result.get('salary_score', 0),
                        'is_salary_related': result.get('is_salary_related', False),
                        'salary_reason': result.get('salary_reason', ''),
                        'photo_score': result.get('photo_score', 0),
                        'is_photo_request': result.get('is_photo_request', False),
                        'photo_reason': result.get('photo_reason', ''),
                        'detected_keywords': result.get('detected_keywords', []),
                        'raw_response': result.get('raw_response', '')
                    }
                    
                    evaluations.append({
                        'message_id': msg['id'],
                        'candidate_id': msg['candidate_id'],
                        'candidate_name': msg['candidate_name'],
                        'content': msg['content'],
                        'created_at': msg['created_at'],
                        'evaluation': evaluation_data,
                        'status': 'evaluated' if result.get('success') else 'failed'
                    })
                    
                    if result.get('success'):
                        evaluated_count += 1
                    else:
                        failed_count += 1
                        
                except Exception as e:
                    self.logger.error(f"[批量评估SSE] 评估消息 {msg['id']} 时出错: {str(e)}")
                    failed_count += 1
                    evaluations.append({
                        'message_id': msg['id'],
                        'candidate_id': msg['candidate_id'],
                        'candidate_name': msg['candidate_name'],
                        'content': msg['content'],
                        'created_at': msg['created_at'],
                        'evaluation': {
                            'success': False,
                            'error': str(e)
                        },
                        'status': 'failed'
                    })
            
            # 统计结果
            salary_messages = [e for e in evaluations if e['evaluation'].get('is_salary_related', False)]
            photo_messages = [e for e in evaluations if e['evaluation'].get('is_photo_request', False)]
            
            # 其他消息 = 评估成功的消息中，既不是薪资也不是照片的消息
            non_salary_messages = [e for e in evaluations 
                                   if not e['evaluation'].get('is_salary_related', False) 
                                   and not e['evaluation'].get('is_photo_request', False)]
            
            non_salary_messages_count = len(non_salary_messages)
            
            # 发送完成事件
            print("\n" + "="*60)
            print(f"✅ 评估完成！")
            print(f"📊 统计结果:")
            print(f"   - 总评估: {len(evaluations)} 条")
            print(f"   - 成功: {evaluated_count} 条")
            print(f"   - 失败: {failed_count} 条")
            print(f"   - 薪资相关: {len(salary_messages)} 条")
            print(f"   - 照片相关: {len(photo_messages)} 条")
            print(f"   - 其他消息: {non_salary_messages_count} 条")
            print("="*60 + "\n")
            
            # 添加关键词评估数量统计
            keyword_evaluated_count = len(relevant_messages)  # 关键词筛选通过的消息数
            self.logger.info(f"[批量评估SSE] 关键词评估通过数量: {keyword_evaluated_count}")
            
            self.send_sse_event('complete', {
                'percent': 100,
                'message': '评估完成！',
                'success': True,
                'total_candidates': len(candidates),
                'total_messages': len(all_messages),
                'total_ai_messages': len(all_messages),
                'keyword_evaluated_count': keyword_evaluated_count,  # 添加关键词评估数量
                'evaluated_count': evaluated_count,
                'failed_count': failed_count,
                'pending_count': 0,
                'salary_messages_count': len(salary_messages),
                'photo_messages_count': len(photo_messages),
                'non_salary_messages_count': non_salary_messages_count,  # 修正为计算后的值
                'all_evaluations': evaluations,
                'timestamp': datetime.now().isoformat()
            })
            
            self.logger.info("[批量评估SSE] ========== SSE批量评估完成 ==========")
            self.logger.info(f"[批量评估SSE] 总评估消息: {len(evaluations)} 条")
            self.logger.info(f"[批量评估SSE] 成功: {evaluated_count} 条")
            self.logger.info(f"[批量评估SSE] 失败: {failed_count} 条")
            
        except Exception as e:
            self.logger.error(f"[批量评估SSE] 批量评估失败: {str(e)}", exc_info=True)
            self.send_sse_event('error', {
                'message': '评估过程中发生错误',
                'error': str(e)
            })
    
    def send_sse_headers(self):
        """发送SSE响应头"""
        self.send_response(200)
        self.send_header('Content-Type', 'text/event-stream; charset=utf-8')
        self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
        self.send_header('Connection', 'keep-alive')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('X-Accel-Buffering', 'no')  # 禁用nginx缓冲
        self.end_headers()
        self.logger.info("[SSE] 已发送SSE响应头")
        
        # 发送一个初始注释以确保连接建立
        self.wfile.write(b': SSE connection established\n\n')
        self.wfile.flush()
    
    def send_sse_event(self, event_type, data):
        """发送SSE事件"""
        try:
            # 构建SSE消息
            message = f"event: {event_type}\ndata: {json.dumps(data, ensure_ascii=False)}\n\n"
            
            # 发送消息
            self.wfile.write(message.encode('utf-8'))
            self.wfile.flush()
            
            # 确保数据被发送
            try:
                # 强制刷新缓冲区
                if hasattr(self.wfile, '_sock'):
                    self.wfile._sock.sendall(b'')  # 触发网络发送
            except:
                pass  # 忽略错误，这只是一个额外的尝试
            
            # 详细日志记录
            if event_type == 'progress':
                self.logger.info(f"[SSE-进度] 发送进度: {data.get('percent', 0)}% - {data.get('message', '')}")
                if data.get('current') and data.get('total'):
                    self.logger.info(f"[SSE-进度] 详细: {data.get('current')}/{data.get('total')} - {data.get('candidate', '')}")
            elif event_type == 'complete':
                self.logger.info(f"[SSE-完成] 评估完成 - 成功: {data.get('evaluated_count', 0)}, 失败: {data.get('failed_count', 0)}")
            elif event_type == 'error':
                self.logger.error(f"[SSE-错误] {data.get('message', '')} - {data.get('error', '')}")
            else:
                self.logger.debug(f"[SSE] 发送事件: {event_type}")
                
            # 打印到控制台以便调试
            if event_type == 'progress':
                print(f"\r[进度] {data.get('percent', 0):3}% - {data.get('message', '')[:50]}", end='', flush=True)
                if data.get('percent', 0) == 100:
                    print()  # 完成时换行
                    
        except Exception as e:
            self.logger.error(f"[SSE] 发送事件失败: {str(e)}")
            print(f"\n[SSE错误] 发送事件失败: {str(e)}")
    
    def handle_batch_evaluate_post(self, data):
        """处理批量评估POST请求"""
        try:
            self.logger.info("========== [批量评估] 开始处理请求 ==========")
            self.logger.debug(f"[批量评估] 请求数据: {data}")
            
            # 获取评估限制
            limit = data.get('limit', 0)
            evaluate_type = data.get('evaluate_type', 'all')  # all, photo, salary
            
            # 🔥 新增：获取日期参数
            start_date = data.get('start_date')
            end_date = data.get('end_date')
            
            self.logger.info(f"[批量评估] 消息条数限制: {limit if limit > 0 else '全部'}")
            self.logger.info(f"[批量评估] 评估类型: {evaluate_type}")
            
            # 🔥 新增：记录日期参数
            if start_date or end_date:
                self.logger.info(f"[批量评估] 开始日期: {start_date or '未指定'}")
                self.logger.info(f"[批量评估] 结束日期: {end_date or '未指定'}")
            else:
                self.logger.info(f"[批量评估] 使用默认时间范围（最近30天）")
            
            self.perform_batch_evaluation(limit, evaluate_type, start_date, end_date)
        except Exception as e:
            self.logger.error(f"[API] 处理批量评估POST请求失败: {str(e)}", exc_info=True)
            raise
    
    def perform_batch_evaluation(self, limit, evaluate_type='all', start_date=None, end_date=None):
        """执行批量评估
        
        Args:
            limit: 消息数量限制，0表示全部
            evaluate_type: 评估类型 (all, photo, salary)
            start_date: 开始日期 (YYYY-MM-DD)
            end_date: 结束日期 (YYYY-MM-DD)
        """
        self.logger.info("=" * 80)
        self.logger.info("[批量评估] ========== 开始执行批量评估 ==========")
        self.logger.info(f"[批量评估] 限制消息数: {limit}")
        self.logger.info(f"[批量评估] 评估类型: {evaluate_type}")
        if start_date or end_date:
            self.logger.info(f"[批量评估] 日期范围: {start_date or '最早'} ~ {end_date or '最新'}")
        self.logger.info("=" * 80)
        
        # 检查是否是SSE请求
        is_sse = False  # 默认不使用SSE，除非明确调用SSE端点
        
        try:
            # 初始化monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[批量评估] Monitor未初始化，正在初始化...")
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                self.logger.info("[批量评估] Monitor初始化完成，连接数据库...")
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[批量评估] 数据库连接失败")
                    self.send_json_response({
                        'success': False,
                        'error': '数据库连接失败'
                    }, status_code=500)
                    return
                self.logger.info("[批量评估] 数据库连接成功")
            else:
                self.logger.info("[批量评估] Monitor已初始化")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            self.logger.info(f"[批量评估] AI评估功能启用状态: {monitor.ai_enabled}")
            if not monitor.ai_enabled:
                self.logger.error("[批量评估] AI评估功能未启用")
                self.send_json_response({
                    'success': False,
                    'error': 'AI评估功能未启用'
                }, status_code=503)
                return
            
            # 获取候选人列表
            self.logger.info("[批量评估] 查询候选人列表...")
            
            # 🔥 新增：根据是否有日期参数选择不同的查询方式
            if start_date or end_date:
                # 使用日期范围查询（通过messages表的created_at）
                self.logger.info("[批量评估] 使用日期范围查询候选人")
                query = """
                SELECT DISTINCT c.id, c.name, c.boss_uid, c.updated_at
                FROM candidates c
                INNER JOIN messages m ON c.id = m.candidate_id
                WHERE 1=1
                """
                params = []
                
                if start_date:
                    query += " AND m.created_at >= %s"
                    params.append(start_date)
                    self.logger.debug(f"[批量评估] 添加开始日期筛选: {start_date}")
                
                if end_date:
                    query += " AND m.created_at < DATE_ADD(%s, INTERVAL 1 DAY)"
                    params.append(end_date)
                    self.logger.debug(f"[批量评估] 添加结束日期筛选: {end_date}")
                
                query += " ORDER BY c.updated_at DESC"
                
                self.logger.debug(f"[批量评估] SQL查询: {query}")
                self.logger.debug(f"[批量评估] 查询参数: {params}")
                
                monitor.cursor.execute(query, params)
            else:
                # 使用默认的30天查询
                self.logger.info("[批量评估] 使用默认30天范围查询候选人")
                query = """
                SELECT c.id, c.name, c.boss_uid, c.updated_at
                FROM candidates c
                WHERE c.updated_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
                GROUP BY c.id, c.name, c.boss_uid, c.updated_at
                ORDER BY c.updated_at DESC
                """
                monitor.cursor.execute(query)
            
            candidates = monitor.cursor.fetchall()
            self.logger.info(f"[批量评估] 找到 {len(candidates)} 个候选人")
            
            # 收集所有消息
            all_messages = []
            candidate_map = {}  # 用于映射消息到候选人
            
            self.logger.info("[批量评估] 开始收集消息...")
            for candidate in candidates:
                candidate_id = candidate['id']
                candidate_name = candidate['name']
                
                # 获取该候选人的消息（只获取AI发送的消息）
                self.logger.debug(f"[批量评估] 查询候选人 #{candidate_id} ({candidate_name}) 的消息")
                
                # 🔥 新增：构建带日期筛选的SQL查询
                msg_query = """
                SELECT id, content, created_at
                FROM messages
                WHERE candidate_id = %s AND sender = '我'
                """
                msg_params = [candidate_id]
                
                # 添加日期筛选条件
                if start_date:
                    msg_query += " AND created_at >= %s"
                    msg_params.append(start_date)
                
                if end_date:
                    msg_query += " AND created_at < DATE_ADD(%s, INTERVAL 1 DAY)"
                    msg_params.append(end_date)
                
                msg_query += " ORDER BY created_at DESC"
                
                # 添加LIMIT（如果有限制）
                if limit > 0:
                    msg_query += " LIMIT %s"
                    msg_params.append(limit)
                
                monitor.cursor.execute(msg_query, msg_params)
                messages = monitor.cursor.fetchall()
                self.logger.debug(f"[批量评估] 候选人 #{candidate_id} 找到 {len(messages)} 条消息")
                
                for msg in messages:
                    all_messages.append({
                        'id': msg['id'],
                        'content': msg['content'],
                        'candidate_id': candidate_id,
                        'candidate_name': candidate_name,
                        'created_at': str(msg['created_at'])
                    })
            
            self.logger.info(f"[批量评估] 共收集到 {len(all_messages)} 条消息")
            
            # 如果有limit限制，只评估前N条
            if limit > 0:
                all_messages = sorted(all_messages, key=lambda x: x['created_at'], reverse=True)[:limit]
                self.logger.info(f"[批量评估] 限制后消息数: {len(all_messages)}")
            
            # 先通过关键词筛选消息
            from config import SALARY_KEYWORDS, PHOTO_REQUEST_KEYWORDS
            self.logger.info(f"[批量评估] 开始关键词筛选 {len(all_messages)} 条消息...")
            self.logger.info(f"[批量评估] 薪资关键词数量: {len(SALARY_KEYWORDS)}")
            self.logger.info(f"[批量评估] 照片关键词数量: {len(PHOTO_REQUEST_KEYWORDS)}")
            
            def check_keywords(text, keywords):
                """检查文本是否包含关键词"""
                matched_keywords = [kw for kw in keywords if kw in text]
                if matched_keywords:
                    self.logger.debug(f"[关键词匹配] 找到关键词: {matched_keywords[:3]}...")  # 只显示前3个
                return len(matched_keywords) > 0
            
            relevant_messages = []  # 关键词通过的消息
            irrelevant_messages = []  # 关键词未通过的消息
            salary_keyword_count = 0  # 薪资关键词匹配数
            photo_keyword_count = 0   # 照片关键词匹配数
            
            for msg in all_messages:
                text = msg['content']
                is_salary = check_keywords(text, SALARY_KEYWORDS)
                is_photo = check_keywords(text, PHOTO_REQUEST_KEYWORDS)
                
                if is_salary:
                    salary_keyword_count += 1
                if is_photo:
                    photo_keyword_count += 1
                    
                if is_salary or is_photo:
                    relevant_messages.append(msg)
                    self.logger.debug(f"[关键词通过] 消息ID: {msg['id']}, 薪资: {is_salary}, 照片: {is_photo}")
                else:
                    irrelevant_messages.append(msg)
            
            self.logger.info(f"[批量评估] 关键词筛选完成 - 通过: {len(relevant_messages)}, 未通过: {len(irrelevant_messages)}")
            self.logger.info(f"[批量评估] 薪资关键词匹配: {salary_keyword_count} 条")
            self.logger.info(f"[批量评估] 照片关键词匹配: {photo_keyword_count} 条")
            
            # 对关键词通过的消息进行AI评估（同时评估薪资和要照片两种信息）
            self.logger.info("=" * 80)
            self.logger.info(f"[批量评估] 开始AI多维度评估")
            self.logger.info(f"[批量评估] 关键词通过的消息数: {len(relevant_messages)}")
            self.logger.info(f"[批量评估] 将同时评估薪资和要照片两种信息")
            self.logger.info("=" * 80)
            
            evaluations = []
            evaluated_count = 0
            failed_count = 0
            original_count = len(all_messages)
            
            for i, msg in enumerate(relevant_messages):
                try:
                    self.logger.info(f"[批量评估] [{i+1}/{len(relevant_messages)}] 开始评估消息 ID: {msg['id']}")
                    self.logger.debug(f"[批量评估] 候选人: {msg['candidate_name']} (ID: {msg['candidate_id']})")
                    self.logger.debug(f"[批量评估] 消息预览: {msg['content'][:100]}...")
                    
                    # 如果是SSE请求，发送进度更新
                    if is_sse:
                        progress_percent = int(((i + 1) / len(relevant_messages)) * 100)
                        self.send_sse_event('progress', {
                            'percent': progress_percent,
                            'current': i + 1,
                            'total': len(relevant_messages),
                            'message': f'正在评估第 {i+1}/{len(relevant_messages)} 条消息',
                            'candidate': msg['candidate_name']
                        })
                    
                    # 使用multi_criteria同时评估薪资和要照片信息
                    self.logger.debug("[批量评估] 调用 evaluate_multi_criteria 进行多维度评估...")
                    result = monitor.salary_analyzer.evaluator.evaluate_multi_criteria(msg['content'])
                    
                    self.logger.info(f"[批量评估] 评估完成 - 薪资分数: {result.get('salary_score', 0)}, "
                                   f"要照片分数: {result.get('photo_score', 0)}")
                    self.logger.debug(f"[批量评估] 详细结果: {json.dumps(result, ensure_ascii=False, indent=2)}")
                    
                    # 将结果格式化为包含薪资和要照片两种评估的结构
                    evaluation_data = {
                        'success': result.get('success', False),
                        'salary_score': result.get('salary_score', 0),
                        'is_salary_related': result.get('is_salary_related', False),
                        'salary_reason': result.get('salary_reason', ''),
                        'photo_score': result.get('photo_score', 0),
                        'is_photo_request': result.get('is_photo_request', False),
                        'photo_reason': result.get('photo_reason', ''),
                        'detected_keywords': result.get('detected_keywords', []),
                        'raw_response': result.get('raw_response', '')
                    }
                    
                    evaluations.append({
                        'message_id': msg['id'],
                        'candidate_id': msg['candidate_id'],
                        'candidate_name': msg['candidate_name'],
                        'content': msg['content'],
                        'created_at': msg['created_at'],
                        'evaluation': evaluation_data,
                        'status': 'evaluated' if result.get('success') else 'failed'
                    })
                    
                    if result.get('success'):
                        evaluated_count += 1
                    else:
                        failed_count += 1
                        
                except Exception as e:
                    self.logger.error(f"[批量评估] 评估消息 {msg['id']} 时出错: {str(e)}")
                    evaluations.append({
                        'message_id': msg['id'],
                        'candidate_id': msg['candidate_id'],
                        'candidate_name': msg['candidate_name'],
                        'content': msg['content'],
                        'created_at': msg['created_at'],
                        'evaluation': {
                            'success': False,
                            'error': str(e),
                            'salary_score': 0,
                            'is_salary_related': False,
                            'salary_reason': f'评估失败: {str(e)}',
                            'photo_score': 0,
                            'is_photo_request': False,
                            'photo_reason': f'评估失败: {str(e)}',
                            'detected_keywords': []
                        },
                        'status': 'failed'
                    })
                    failed_count += 1
            
            # 对关键词未通过的消息，直接标记为不相关，不进行AI评估
            for msg in irrelevant_messages:
                evaluations.append({
                    'message_id': msg['id'],
                    'candidate_id': msg['candidate_id'],
                    'candidate_name': msg['candidate_name'],
                    'content': msg['content'],
                    'created_at': msg['created_at'],
                    'evaluation': {
                        'success': True,
                        'salary_score': 0,
                        'is_salary_related': False,
                        'salary_reason': '关键词筛选未通过，无需AI评估',
                        'photo_score': 0,
                        'is_photo_request': False,
                        'photo_reason': '关键词筛选未通过，无需AI评估',
                        'detected_keywords': []
                    },
                    'status': 'filtered'
                })
            
            self.logger.info(f"[批量评估] 完成评估，共评估 {len(evaluations)} 条消息 (成功: {evaluated_count}, 失败: {failed_count})")
            
            # 计算待评估数
            pending_count = 0
            if limit > 0 and original_count > len(all_messages):
                pending_count = original_count - len(all_messages)
            
            # 统计结果 - 分别统计薪资相关和要照片相关消息
            self.logger.info("=" * 80)
            self.logger.info("[批量评估] 开始统计分类结果...")
            
            salary_messages = [e for e in evaluations if e.get('evaluation', {}).get('is_salary_related', False)]
            photo_messages = [e for e in evaluations if e.get('evaluation', {}).get('is_photo_request', False)]
            
            # 其他消息 = 评估成功的消息中，既不是薪资也不是照片的消息
            # 注意：要从evaluations（已评估的消息）中计算，不是all_messages
            non_salary_messages = [e for e in evaluations 
                                   if not e.get('evaluation', {}).get('is_salary_related', False) 
                                   and not e.get('evaluation', {}).get('is_photo_request', False)
                                   and e.get('status') == 'evaluated']
            
            non_salary_messages_count = len(non_salary_messages)
            
            # 统计薪资和照片的去重ID（用于调试）
            salary_and_photo_ids = set()
            for msg in salary_messages:
                salary_and_photo_ids.add(msg.get('message_id'))
            for msg in photo_messages:
                salary_and_photo_ids.add(msg.get('message_id'))
            
            self.logger.info("=" * 80)
            self.logger.info("[批量评估] 分类统计结果:")
            self.logger.info(f"  - 总AI消息数: {len(all_messages)} 条")
            self.logger.info(f"  - 已评估消息: {len(evaluations)} 条")
            self.logger.info(f"  - 薪资相关消息: {len(salary_messages)} 条")
            self.logger.info(f"  - 要照片相关消息: {len(photo_messages)} 条")
            self.logger.info(f"  - 薪资或照片相关（去重）: {len(salary_and_photo_ids)} 条")
            self.logger.info(f"  - 其他消息: {non_salary_messages_count} 条")
            self.logger.info(f"  - 验证: {len(salary_messages)} + {len(photo_messages)} - 重叠 + {non_salary_messages_count} = {len(evaluations)}")
            self.logger.info("=" * 80)
            
            # 添加关键词评估数量统计
            keyword_evaluated_count = len(relevant_messages)  # 关键词筛选通过的消息数
            self.logger.info(f"[批量评估] 关键词评估通过数量: {keyword_evaluated_count}")
            
            response_data = {
                'success': True,
                'total_candidates': len(candidates),
                'total_messages': len(evaluations),
                'total_ai_messages': len(all_messages),
                'keyword_evaluated_count': keyword_evaluated_count,  # 添加关键词评估数量
                'evaluated_count': evaluated_count,
                'failed_count': failed_count,
                'pending_count': pending_count,
                'salary_messages_count': len(salary_messages),
                'photo_messages_count': len(photo_messages),
                'non_salary_messages_count': non_salary_messages_count,  # 修正为计算后的值
                'salary_messages': salary_messages[:100],
                'photo_messages': photo_messages[:100],
                'all_evaluations': evaluations,
                'timestamp': datetime.now().isoformat()
            }
            
            # 保存评估统计结果到数据库
            self.logger.info("[批量评估] 保存评估统计结果到数据库...")
            try:
                self.save_evaluation_statistics(response_data)
                self.logger.info("[批量评估] 评估统计结果保存成功")
            except Exception as e:
                self.logger.error(f"[批量评估] 保存评估统计结果失败: {str(e)}")
                self.logger.error(f"[批量评估] 错误堆栈: {traceback.format_exc()}")
            
            self.logger.info("[批量评估] 准备返回响应给前端...")
            self.logger.debug(f"[批量评估] 响应数据预览: total_candidates={response_data['total_candidates']}, "
                            f"salary_count={response_data['salary_messages_count']}, "
                            f"photo_count={response_data['photo_messages_count']}")
            
            self.send_json_response(response_data)
            
            self.logger.info("=" * 80)
            self.logger.info("[批量评估] ========== 批量评估完成 ==========")
            self.logger.info(f"[批量评估] 总评估消息: {len(evaluations)} 条")
            self.logger.info(f"[批量评估] 成功: {evaluated_count} 条")
            self.logger.info(f"[批量评估] 失败: {failed_count} 条")
            self.logger.info(f"[批量评估] 薪资相关: {len(salary_messages)} 条")
            self.logger.info(f"[批量评估] 要照片相关: {len(photo_messages)} 条")
            self.logger.info("=" * 80)
            
        except Exception as e:
            self.logger.error(f"[批量评估] 批量评估失败: {str(e)}", exc_info=True)
            import traceback
            traceback.print_exc()
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def send_json_response(self, data, status_code=200):
        """发送JSON响应"""
        try:
            self.send_response(status_code)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            
            # 使用UTF-8编码确保中文正确显示
            json_str = json.dumps(data, ensure_ascii=False, indent=2)
            response_bytes = json_str.encode('utf-8')
            
            self.logger.debug(f"[JSON响应] 发送响应，大小: {len(response_bytes)} 字节")
            self.wfile.write(response_bytes)
            
        except Exception as e:
            self.logger.error(f"[JSON响应] 发送响应失败: {str(e)}", exc_info=True)
            # 如果JSON编码失败，尝试发送错误响应
            try:
                error_response = {
                    'success': False,
                    'error': 'Failed to encode response',
                    'error_detail': str(e)
                }
                error_bytes = json.dumps(error_response, ensure_ascii=False).encode('utf-8')
                self.wfile.write(error_bytes)
            except:
                pass
    
    def handle_export_evaluations_post(self, data):
        """处理导出评估结果POST请求"""
        try:
            self.logger.info("========== 开始处理导出请求 ==========")
            print("\n" + "="*60)
            print("📤 收到导出请求")
            print("="*60)
            
            evaluations = data.get('evaluations', [])
            self.logger.info(f"接收到评估数据条数: {len(evaluations)}")
            print(f"📊 接收到的评估数据条数: {len(evaluations)}")
            
            if len(evaluations) == 0:
                self.logger.warning("没有可导出的评估数据")
                print("⚠️  没有可导出的评估数据")
                self.send_json_response({
                    'success': False,
                    'error': 'No evaluations to export'
                }, status_code=400)
                print("="*60 + "\n")
                return
            
            # 显示评估数据样本
            if len(evaluations) > 0:
                print(f"📝 第一条评估数据预览:")
                first_eval = evaluations[0]
                print(f"  - message_id: {first_eval.get('message_id')}")
                print(f"  - candidate_id: {first_eval.get('candidate_id')}")
                print(f"  - candidate_name: {first_eval.get('candidate_name')}")
                print(f"  - 是否薪资相关: {first_eval.get('evaluation', {}).get('is_salary_related', 'N/A')}")
            
            # 导出到SQLite数据库
            self.logger.info("开始导出到SQLite数据库...")
            print("💾 开始导出到SQLite数据库...")
            export_result = self.export_to_sqlite(evaluations)
            self.logger.info(f"导出完成，共导出 {export_result['count']} 条记录")
            print(f"✅ 导出完成！共导出 {export_result['count']} 条记录")
            print(f"📁 数据库路径: {export_result['db_path']}")
            
            response_data = {
                'success': True,
                'exported_count': export_result['count'],
                'db_path': export_result['db_path'],
                'timestamp': datetime.now().isoformat()
            }
            
            self.logger.info("========== 导出请求处理成功 ==========")
            print("="*60 + "\n")
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"导出失败: {str(e)}", exc_info=True)
            print(f"❌ 导出失败: {str(e)}")
            print("="*60 + "\n")
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_evaluate_user_messages_post(self, data):
        """处理用户消息评估POST请求"""
        self.logger.info(f"[API] 收到用户消息评估POST请求: {data}")
        try:
            limit = data.get('limit', 50)
            self.logger.info(f"[API] 评估消息限制: {limit}")
            self.perform_user_messages_evaluation(limit)
        except Exception as e:
            self.logger.error(f"[API] 处理用户消息评估POST请求失败: {str(e)}", exc_info=True)
            raise
    
    def perform_user_messages_evaluation(self, limit):
        """执行用户消息评估"""
        self.logger.info("=" * 80)
        self.logger.info("[用户消息评估] ========== 开始执行用户消息评估 ==========")
        self.logger.info(f"[用户消息评估] 限制每个候选人消息数: {limit}")
        self.logger.info("=" * 80)
        
        try:
            # 初始化monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[用户消息评估] Monitor未初始化，正在初始化...")
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[用户消息评估] 数据库连接失败")
                    self.send_json_response({'success': False, 'error': '数据库连接失败'}, status_code=500)
                    return
                self.logger.info("[用户消息评估] Monitor初始化成功")
            else:
                self.logger.info("[用户消息评估] Monitor已初始化")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            # 检查AI评估是否可用
            if not monitor.ai_enabled:
                self.logger.error("[用户消息评估] AI评估功能未启用")
                self.send_json_response({
                    'success': False,
                    'error': 'AI评估功能未启用'
                }, status_code=503)
                return
            
            # 获取候选人列表
            self.logger.info("[用户消息评估] 正在获取候选人列表...")
            query = """
            SELECT c.id, c.name, c.boss_uid, c.updated_at
            FROM candidates c
            WHERE c.updated_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
            GROUP BY c.id, c.name, c.boss_uid, c.updated_at
            ORDER BY c.updated_at DESC
            """
            monitor.cursor.execute(query)
            candidates = monitor.cursor.fetchall()
            self.logger.info(f"[用户消息评估] 找到 {len(candidates)} 个候选人")
            
            # 收集所有用户发送的消息（不是AI的消息）
            self.logger.info("[用户消息评估] 正在收集用户消息...")
            all_messages = []
            for idx, candidate in enumerate(candidates, 1):
                candidate_id = candidate['id']
                candidate_name = candidate['name']
                
                msg_query = """
                SELECT id, content, created_at
                FROM messages
                WHERE candidate_id = %s AND sender != '我'
                ORDER BY created_at DESC
                LIMIT %s
                """
                monitor.cursor.execute(msg_query, (candidate_id, limit))
                messages = monitor.cursor.fetchall()
                
                self.logger.debug(f"[用户消息评估] 候选人 {idx}/{len(candidates)}: {candidate_name} - {len(messages)} 条消息")
                
                for msg in messages:
                    all_messages.append({
                        'id': msg['id'],
                        'content': msg['content'],
                        'candidate_id': candidate_id,
                        'candidate_name': candidate_name,
                        'created_at': str(msg['created_at'])
                    })
            
            self.logger.info(f"[用户消息评估] 共收集到 {len(all_messages)} 条用户消息")
            
            # 显示前几条消息用于调试
            if len(all_messages) > 0:
                self.logger.info("[用户消息评估] 消息示例（前5条）:")
                for idx, msg in enumerate(all_messages[:5], 1):
                    content_preview = msg['content'][:50] + ('...' if len(msg['content']) > 50 else '')
                    self.logger.info(f"  {idx}. [{msg['candidate_name']}] {content_preview}")
            
            # 关键词筛选
            from config import SENSITIVE_WORDS, TRANSFER_TO_HUMAN_KEYWORDS
            self.logger.info(f"[用户消息评估] 开始关键词筛选...")
            self.logger.info(f"[用户消息评估] 敏感词数量: {len(SENSITIVE_WORDS)}")
            self.logger.info(f"[用户消息评估] 转人工关键词数量: {len(TRANSFER_TO_HUMAN_KEYWORDS)}")
            
            def check_keywords(text, keywords):
                """检查文本是否包含关键词"""
                found = []
                for keyword in keywords:
                    if keyword in text:
                        found.append(keyword)
                return found
            
            keyword_filtered_messages = []  # 关键词筛选通过的消息（需要AI评估）
            normal_messages = []  # 正常消息（不需要AI评估）
            
            # 统计不同类型的消息
            sensitive_only_count = 0  # 仅敏感词
            transfer_only_count = 0   # 仅转人工
            both_count = 0            # 既敏感又转人工
            
            self.logger.info("[用户消息评估] 开始逐条检测关键词...")
            
            for idx, msg in enumerate(all_messages, 1):
                # 检查敏感词
                found_sensitive = check_keywords(msg['content'], SENSITIVE_WORDS)
                # 检查转人工关键词
                found_transfer = check_keywords(msg['content'], TRANSFER_TO_HUMAN_KEYWORDS)
                
                if found_sensitive or found_transfer:
                    msg['detected_keywords'] = {
                        'sensitive': found_sensitive,
                        'transfer_to_human': found_transfer
                    }
                    keyword_filtered_messages.append(msg)
                    
                    # 分类统计
                    if found_sensitive and found_transfer:
                        both_count += 1
                        msg_type = "敏感+转人工"
                    elif found_sensitive:
                        sensitive_only_count += 1
                        msg_type = "仅敏感"
                    else:
                        transfer_only_count += 1
                        msg_type = "仅转人工"
                    
                    # 详细日志
                    self.logger.info(f"[关键词检测] [{msg_type}] 消息 {idx}/{len(all_messages)}")
                    self.logger.info(f"  ├─ 候选人: {msg['candidate_name']}")
                    self.logger.info(f"  ├─ 内容: {msg['content']}")
                    if found_sensitive:
                        self.logger.info(f"  ├─ 敏感词: {', '.join(found_sensitive)}")
                    if found_transfer:
                        self.logger.info(f"  └─ 转人工词: {', '.join(found_transfer)}")
                else:
                    normal_messages.append(msg)
                    self.logger.debug(f"[关键词检测] [正常] 消息 {idx}/{len(all_messages)} - {msg['content'][:30]}...")
            
            self.logger.info("=" * 80)
            self.logger.info("[用户消息评估] 关键词筛选结果统计:")
            self.logger.info(f"  ├─ 总消息数: {len(all_messages)}")
            self.logger.info(f"  ├─ 需AI评估: {len(keyword_filtered_messages)}")
            self.logger.info(f"  │   ├─ 仅敏感词: {sensitive_only_count}")
            self.logger.info(f"  │   ├─ 仅转人工: {transfer_only_count}")
            self.logger.info(f"  │   └─ 既敏感又转人工: {both_count}")
            self.logger.info(f"  └─ 正常消息: {len(normal_messages)}")
            self.logger.info("=" * 80)
            
            # 对关键词筛选出的消息进行AI评估
            evaluations = []
            ai_evaluated_count = 0
            ai_failed_count = 0
            
            if keyword_filtered_messages:
                self.logger.info("=" * 80)
                self.logger.info(f"[用户消息评估] 开始AI评估 - 共 {len(keyword_filtered_messages)} 条消息需要评估")
                self.logger.info("=" * 80)
                
                for idx, msg in enumerate(keyword_filtered_messages, 1):
                    self.logger.info(f"[用户消息评估] AI评估进度: {idx}/{len(keyword_filtered_messages)}")
                    self.logger.debug(f"[用户消息评估] 评估消息 - 候选人: {msg['candidate_name']}, "
                                    f"内容长度: {len(msg['content'])} 字符")
                    
                    try:
                        # 构造AI评估提示词
                        detected_keywords = msg.get('detected_keywords', {})
                        sensitive_keywords = detected_keywords.get('sensitive', [])
                        transfer_keywords = detected_keywords.get('transfer_to_human', [])
                        
                        # 使用AI评估器进行深度评估
                        ai_prompt = self._build_user_message_evaluation_prompt(
                            msg['content'], 
                            sensitive_keywords, 
                            transfer_keywords
                        )
                        
                        self.logger.debug(f"[用户消息评估] 调用AI评估器...")
                        
                        # 直接调用AI API进行评估
                        import requests
                        data = {
                            "model": "deepseek-chat",
                            "messages": [{"role": "user", "content": ai_prompt}],
                            "temperature": 0.1,
                            "max_tokens": 500
                        }
                        
                        response = requests.post(
                            monitor.salary_analyzer.evaluator.base_url,
                            headers=monitor.salary_analyzer.evaluator.headers,
                            json=data,
                            timeout=30
                        )
                        
                        if response.status_code == 200:
                            result = response.json()
                            content = result['choices'][0]['message']['content'].strip()
                            
                            # 解析JSON响应
                            import json as json_lib
                            try:
                                ai_result = json_lib.loads(content)
                                ai_result['success'] = True
                            except:
                                # 如果解析失败，尝试提取关键信息
                                ai_result = {
                                    'success': False,
                                    'score': 50,
                                    'is_sensitive': len(sensitive_keywords) > 0,
                                    'is_transfer_request': len(transfer_keywords) > 0,
                                    'reason': 'AI响应解析失败'
                                }
                        else:
                            ai_result = None
                        
                        if ai_result and ai_result.get('success'):
                            ai_evaluated_count += 1
                            self.logger.info(f"[用户消息评估] ✅ AI评估成功 - 消息ID: {msg['id']}")
                            
                            evaluation = {
                                'message_id': msg['id'],
                                'candidate_id': msg['candidate_id'],
                                'candidate_name': msg['candidate_name'],
                                'content': msg['content'],
                                'created_at': msg['created_at'],
                                'evaluation': {
                                    'success': True,
                                    'score': ai_result.get('score', 0),
                                    'is_sensitive': ai_result.get('is_sensitive', False),
                                    'is_transfer_request': ai_result.get('is_transfer_request', False),
                                    'reason': ai_result.get('reason', ''),
                                    'detected_keywords': detected_keywords,
                                    'evaluation_method': 'ai'  # 标记为AI评估
                                },
                                'status': 'evaluated'
                            }
                        else:
                            ai_failed_count += 1
                            self.logger.warning(f"[用户消息评估] ⚠️ AI评估失败，使用关键词结果 - 消息ID: {msg['id']}")
                            
                            # AI评估失败，使用关键词检测结果
                            evaluation = {
                                'message_id': msg['id'],
                                'candidate_id': msg['candidate_id'],
                                'candidate_name': msg['candidate_name'],
                                'content': msg['content'],
                                'created_at': msg['created_at'],
                                'evaluation': {
                                    'success': True,
                                    'score': 100 if sensitive_keywords else 50,
                                    'is_sensitive': len(sensitive_keywords) > 0,
                                    'is_transfer_request': len(transfer_keywords) > 0,
                                    'reason': self._build_keyword_reason(sensitive_keywords, transfer_keywords),
                                    'detected_keywords': detected_keywords,
                                    'evaluation_method': 'keyword_only'  # 标记为仅关键词
                                },
                                'status': 'evaluated'
                            }
                        
                        # 添加延迟避免API限流
                        time.sleep(0.1)
                        
                    except Exception as e:
                        ai_failed_count += 1
                        self.logger.error(f"[用户消息评估] ❌ 评估异常 - 消息ID: {msg['id']}, 错误: {str(e)}")
                        
                        # 评估异常，使用关键词检测结果
                        evaluation = {
                            'message_id': msg['id'],
                            'candidate_id': msg['candidate_id'],
                            'candidate_name': msg['candidate_name'],
                            'content': msg['content'],
                            'created_at': msg['created_at'],
                            'evaluation': {
                                'success': False,
                                'error': str(e),
                                'score': 100 if sensitive_keywords else 50,
                                'is_sensitive': len(sensitive_keywords) > 0,
                                'is_transfer_request': len(transfer_keywords) > 0,
                                'reason': self._build_keyword_reason(sensitive_keywords, transfer_keywords),
                                'detected_keywords': detected_keywords,
                                'evaluation_method': 'keyword_only'
                            },
                            'status': 'failed'
                        }
                    
                    # 无论成功还是失败，都只添加一次
                    evaluations.append(evaluation)
                
                self.logger.info("=" * 80)
                self.logger.info(f"[用户消息评估] AI评估完成 - 成功: {ai_evaluated_count}, 失败: {ai_failed_count}")
                self.logger.info("=" * 80)
            
            # 正常消息也加入评估结果（标记为正常）
            for msg in normal_messages:
                evaluations.append({
                    'message_id': msg['id'],
                    'candidate_id': msg['candidate_id'],
                    'candidate_name': msg['candidate_name'],
                    'content': msg['content'],
                    'created_at': msg['created_at'],
                    'evaluation': {
                        'success': True,
                        'score': 0,
                        'is_sensitive': False,
                        'is_transfer_request': False,
                        'reason': '未检测到敏感内容或转人工请求',
                        'detected_keywords': {'sensitive': [], 'transfer_to_human': []},
                        'evaluation_method': 'keyword_filter'
                    },
                    'status': 'normal'
                })
            
            # 统计结果 - 详细分类
            sensitive_count = sum(1 for e in evaluations if e['evaluation'].get('is_sensitive', False))
            transfer_count = sum(1 for e in evaluations if e['evaluation'].get('is_transfer_request', False))
            
            # 细分统计
            sensitive_only = []
            transfer_only = []
            both_sensitive_and_transfer = []
            
            for e in evaluations:
                eval_data = e.get('evaluation', {})
                is_sensitive = eval_data.get('is_sensitive', False)
                is_transfer = eval_data.get('is_transfer_request', False)
                
                if is_sensitive and is_transfer:
                    both_sensitive_and_transfer.append(e)
                elif is_sensitive:
                    sensitive_only.append(e)
                elif is_transfer:
                    transfer_only.append(e)
            
            response_data = {
                'success': True,
                'total_candidates': len(candidates),
                'total_messages': len(evaluations),
                'keyword_filtered_count': len(keyword_filtered_messages),
                'ai_evaluated_count': ai_evaluated_count,
                'ai_failed_count': ai_failed_count,
                'sensitive_messages_count': sensitive_count,
                'transfer_request_count': transfer_count,
                'normal_messages_count': len(normal_messages),
                'all_evaluations': evaluations,
                'timestamp': datetime.now().isoformat()
            }
            
            self.logger.info("=" * 80)
            self.logger.info("[用户消息评估] ========== 评估完成 ==========")
            self.logger.info("=" * 80)
            self.logger.info("[评估统计] 总体数据:")
            self.logger.info(f"  ├─ 总候选人数: {len(candidates)}")
            self.logger.info(f"  ├─ 总消息数: {len(evaluations)}")
            self.logger.info(f"  ├─ 关键词筛选: {len(keyword_filtered_messages)}")
            self.logger.info(f"  │   ├─ AI评估成功: {ai_evaluated_count}")
            self.logger.info(f"  │   └─ AI评估失败: {ai_failed_count}")
            self.logger.info(f"  └─ 正常消息: {len(normal_messages)}")
            self.logger.info("")
            self.logger.info("[评估统计] 分类结果:")
            self.logger.info(f"  ├─ 敏感消息总数: {sensitive_count}")
            self.logger.info(f"  │   ├─ 仅敏感: {len(sensitive_only)}")
            self.logger.info(f"  │   └─ 敏感+转人工: {len(both_sensitive_and_transfer)}")
            self.logger.info(f"  ├─ 转人工请求总数: {transfer_count}")
            self.logger.info(f"  │   ├─ 仅转人工: {len(transfer_only)}")
            self.logger.info(f"  │   └─ 敏感+转人工: {len(both_sensitive_and_transfer)}")
            self.logger.info(f"  └─ 正常消息: {len(normal_messages)}")
            self.logger.info("")
            self.logger.info("[评估统计] 数据验证:")
            expected_total = len(sensitive_only) + len(transfer_only) + len(both_sensitive_and_transfer) + len(normal_messages)
            actual_total = len(evaluations)
            if expected_total == actual_total:
                self.logger.info(f"  ✓ 统计一致: {expected_total} = {actual_total}")
            else:
                self.logger.warning(f"  ⚠ 统计不一致: 预期{expected_total} != 实际{actual_total}")
            self.logger.info("=" * 80)
            
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"[用户消息评估] 评估失败: {str(e)}", exc_info=True)
            import traceback
            traceback.print_exc()
            self.send_json_response({'success': False, 'error': str(e)}, status_code=500)
    
    def _build_user_message_evaluation_prompt(self, content, sensitive_keywords, transfer_keywords):
        """构建用户消息评估的AI提示词"""
        prompt = """你是一个专业的客服消息分析专家。请分析以下用户消息是否包含敏感信息或转人工请求。

分析维度：
1. 敏感信息检测：
   - 不文明用语、骂人词汇
   - 政治敏感内容
   - 情绪激动、生气、抱怨
   
2. 转人工请求检测：
   - 明确要求转人工、真人服务
   - 对机器人服务不满
   - 询问是否有真人在线

"""
        
        if sensitive_keywords:
            prompt += f"\n已检测到可能的敏感关键词: {', '.join(sensitive_keywords)}\n"
        if transfer_keywords:
            prompt += f"\n已检测到可能的转人工关键词: {', '.join(transfer_keywords)}\n"
        
        prompt += f"""
请按照以下JSON格式返回结果：
{{
    "score": 评分(0-100, 越高表示越敏感或越需要转人工),
    "is_sensitive": true/false (是否包含敏感信息),
    "is_transfer_request": true/false (是否为转人工请求),
    "reason": "详细的判断依据和理由"
}}

用户消息内容：
{content}
"""
        return prompt
    
    def _build_keyword_reason(self, sensitive_keywords, transfer_keywords):
        """构建基于关键词的评估理由"""
        reasons = []
        if sensitive_keywords:
            reasons.append(f"检测到敏感关键词: {', '.join(sensitive_keywords)}")
        if transfer_keywords:
            reasons.append(f"检测到转人工关键词: {', '.join(transfer_keywords)}")
        return '; '.join(reasons) if reasons else '未检测到特殊内容'
    
    def handle_evaluate_reply_reasonable_post(self, data):
        """处理回复合理评估POST请求"""
        self.logger.info(f"[API] 收到回复合理评估POST请求: {data}")
        try:
            limit = data.get('limit', 50)
            start_date = data.get('start_date', None)
            end_date = data.get('end_date', None)
            
            self.logger.info(f"[API] 评估消息对限制: {limit}")
            self.logger.info(f"[API] 开始日期: {start_date or '不限制'}")
            self.logger.info(f"[API] 结束日期: {end_date or '不限制'}")
            
            self.perform_reply_reasonable_evaluation(limit, start_date, end_date)
        except Exception as e:
            self.logger.error(f"[API] 处理回复合理评估POST请求失败: {str(e)}", exc_info=True)
            raise
    
    def perform_reply_reasonable_evaluation(self, limit, start_date=None, end_date=None):
        """执行回复合理评估"""
        self.logger.info("=" * 80)
        self.logger.info("[回复合理评估] ========== 开始执行回复合理评估 ==========")
        self.logger.info(f"[回复合理评估] 限制消息对数: {limit}")
        self.logger.info(f"[回复合理评估] 开始日期: {start_date or '不限制'}")
        self.logger.info(f"[回复合理评估] 结束日期: {end_date or '不限制'}")
        self.logger.info("=" * 80)
        
        try:
            # 初始化monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[回复合理评估] Monitor未初始化，正在初始化...")
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                self.logger.info("[回复合理评估] Monitor初始化完成，连接数据库...")
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[回复合理评估] 数据库连接失败")
                    self.send_json_response({
                        'success': False,
                        'error': '数据库连接失败'
                    }, status_code=500)
                    return
                self.logger.info("[回复合理评估] 数据库连接成功")
            else:
                self.logger.info("[回复合理评估] Monitor已初始化")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            self.logger.info(f"[回复合理评估] AI评估功能启用状态: {monitor.ai_enabled}")
            if not monitor.ai_enabled:
                self.logger.error("[回复合理评估] AI评估功能未启用")
                self.send_json_response({
                    'success': False,
                    'error': 'AI评估功能未启用'
                }, status_code=503)
                return
            
            # 获取用户-AI消息对（支持日期范围）
            self.logger.info(f"[回复合理评估] 开始获取用户-AI消息对...")
            self.logger.info(f"[回复合理评估] limit参数: {limit} ({'全部' if limit == 0 else '限制'})")
            
            # 如果提供了日期参数，使用日期范围查询
            if start_date or end_date:
                self.logger.info(f"[回复合理评估] 使用日期范围查询")
                message_pairs = monitor.get_user_ai_message_pairs(
                    limit=limit,
                    start_date=start_date,
                    end_date=end_date
                )
            else:
                self.logger.info(f"[回复合理评估] 使用默认天数查询（最近30天）")
                message_pairs = monitor.get_user_ai_message_pairs(days=30, limit=limit)
            
            self.logger.info(f"[回复合理评估] 共获取 {len(message_pairs)} 对消息")
            if limit == 0:
                self.logger.info(f"[回复合理评估] 由于limit=0，已获取全部消息对")
            
            if len(message_pairs) == 0:
                # 构建详细的提示信息
                date_info = ""
                if start_date and end_date:
                    if start_date == end_date:
                        date_info = f"{start_date}这天"
                    else:
                        date_info = f"{start_date}至{end_date}期间"
                elif start_date:
                    date_info = f"从{start_date}开始"
                elif end_date:
                    date_info = f"到{end_date}为止"
                else:
                    date_info = "最近30天内"
                
                error_msg = f"{date_info}没有可评估的消息对。\n可能原因：\n1. 该时间段内只有用户消息，没有AI回复\n2. 该时间段内只有AI消息，没有用户消息\n3. 该时间段内确实没有消息\n\n请选择其他日期重试。"
                
                self.logger.warning(f"[回复合理评估] {error_msg.replace(chr(10), ' ')}")  # 日志中去掉换行
                self.send_json_response({
                    'success': False,
                    'error': error_msg,
                    'message_pairs_count': 0,
                    'date_range': {
                        'start_date': start_date,
                        'end_date': end_date
                    }
                }, status_code=200)  # 改为200，这不是服务器错误
                return
            
            # 对每对消息进行评估
            evaluations = []
            evaluated_count = 0
            reasonable_count = 0
            failed_count = 0
            
            self.logger.info(f"[回复合理评估] 开始AI评估...")
            for i, pair in enumerate(message_pairs):
                try:
                    self.logger.info(f"[回复合理评估] [{i+1}/{len(message_pairs)}] 开始评估消息对 ID: {pair.get('pair_id')}")
                    self.logger.debug(f"[回复合理评估] 候选人: {pair.get('candidate_name')} (ID: {pair.get('candidate_id')})")
                    self.logger.debug(f"[回复合理评估] 用户消息预览: {pair.get('user_message', '')[:50]}...")
                    self.logger.debug(f"[回复合理评估] AI回复预览: {pair.get('ai_reply', '')[:50]}...")
                    
                    # 🔥 关键修复：如果存在current_prompt，使用最新的提示词进行评估
                    if EnhancedHTTPRequestHandler.current_prompt:
                        self.logger.info("[回复合理评估] 检测到current_prompt，使用最新提示词进行评估")
                        self.logger.debug(f"[回复合理评估] current_prompt长度: {len(EnhancedHTTPRequestHandler.current_prompt)}")
                        # 使用自定义提示词进行评估
                        result = monitor.salary_analyzer.evaluator.evaluate_with_custom_prompt(
                            pair.get('user_message', ''),
                            pair.get('ai_reply', ''),
                            EnhancedHTTPRequestHandler.current_prompt
                        )
                        self.logger.info("[回复合理评估] 使用最新提示词评估完成")
                    else:
                        self.logger.info("[回复合理评估] 未检测到current_prompt，使用默认提示词进行评估")
                        # 使用默认评估方法
                        result = monitor.salary_analyzer.evaluator.evaluate_reply_reasonable(
                            pair.get('user_message', ''),
                            pair.get('ai_reply', '')
                        )
                    
                    self.logger.info(f"[回复合理评估] 评估完成 - 分数: {result.get('score', 0)}, 是否合理: {result.get('is_reasonable', False)}")
                    self.logger.debug(f"[回复合理评估] 详细结果: {json.dumps(result, ensure_ascii=False, indent=2)}")
                    
                    evaluation_data = {
                        'success': result.get('success', False),
                        'score': result.get('score', 0),
                        'is_reasonable': result.get('is_reasonable', False),
                        'reason': result.get('reason', ''),
                        'strengths': result.get('strengths', []),
                        'weaknesses': result.get('weaknesses', []),
                        'raw_response': result.get('raw_response', '')
                    }
                    
                    evaluations.append({
                        'pair_id': pair.get('pair_id'),
                        'candidate_id': pair.get('candidate_id'),
                        'candidate_name': pair.get('candidate_name'),
                        'user_message': pair.get('user_message', ''),
                        'ai_reply': pair.get('ai_reply', ''),
                        'created_at': pair.get('created_at'),
                        'evaluation': evaluation_data,
                        'status': 'evaluated' if result.get('success') else 'failed'
                    })
                    
                    if result.get('success'):
                        evaluated_count += 1
                        if result.get('is_reasonable', False):
                            reasonable_count += 1
                    else:
                        failed_count += 1
                        
                except Exception as e:
                    self.logger.error(f"[回复合理评估] 评估消息对 {pair.get('pair_id')} 时出错: {str(e)}")
                    evaluations.append({
                        'pair_id': pair.get('pair_id'),
                        'candidate_id': pair.get('candidate_id'),
                        'candidate_name': pair.get('candidate_name'),
                        'user_message': pair.get('user_message', ''),
                        'ai_reply': pair.get('ai_reply', ''),
                        'created_at': pair.get('created_at'),
                        'evaluation': {
                            'success': False,
                            'error': str(e),
                            'score': 0,
                            'is_reasonable': False,
                            'reason': f'评估失败: {str(e)}',
                            'strengths': [],
                            'weaknesses': []
                        },
                        'status': 'failed'
                    })
                    failed_count += 1
            
            self.logger.info(f"[回复合理评估] 完成评估，共评估 {len(evaluations)} 对消息 (成功: {evaluated_count}, 合理: {reasonable_count}, 失败: {failed_count})")
            
            # 统计结果
            self.logger.info("=" * 80)
            self.logger.info("[回复合理评估] 开始统计分类结果...")
            
            reasonable_pairs = [e for e in evaluations if e.get('evaluation', {}).get('is_reasonable', False) and e.get('status') == 'evaluated']
            unreasonable_pairs = [e for e in evaluations if not e.get('evaluation', {}).get('is_reasonable', False) and e.get('status') == 'evaluated']
            
            self.logger.info("=" * 80)
            self.logger.info("[回复合理评估] 分类统计结果:")
            self.logger.info(f"  - 合理回复: {len(reasonable_pairs)} 对")
            self.logger.info(f"  - 不合理回复: {len(unreasonable_pairs)} 对")
            self.logger.info("=" * 80)
            
            response_data = {
                'success': True,
                'total_pairs': len(evaluations),
                'evaluated_count': evaluated_count,
                'reasonable_count': reasonable_count,
                'unreasonable_count': len(unreasonable_pairs),
                'failed_count': failed_count,
                'reasonable_pairs': reasonable_pairs[:100],
                'unreasonable_pairs': unreasonable_pairs[:100],
                'all_evaluations': evaluations,
                'timestamp': datetime.now().isoformat()
            }
            
            # 保存评估统计结果到数据库
            self.logger.info("[回复合理评估] 保存评估统计结果到数据库...")
            try:
                self.save_reply_reasonable_statistics(response_data)
                self.logger.info("[回复合理评估] 评估统计结果保存成功")
            except Exception as e:
                self.logger.error(f"[回复合理评估] 保存评估统计结果失败: {str(e)}")
                self.logger.error(f"[回复合理评估] 错误堆栈: {traceback.format_exc()}")
            
            self.logger.info("[回复合理评估] 准备返回响应给前端...")
            self.send_json_response(response_data)
            
            self.logger.info("=" * 80)
            self.logger.info("[回复合理评估] ========== 回复合理评估完成 ==========")
            self.logger.info(f"[回复合理评估] 总评估消息对: {len(evaluations)}")
            self.logger.info(f"[回复合理评估] 成功: {evaluated_count} 对")
            self.logger.info(f"[回复合理评估] 合理: {reasonable_count} 对")
            self.logger.info(f"[回复合理评估] 不合理: {len(unreasonable_pairs)} 对")
            self.logger.info("=" * 80)
            
        except Exception as e:
            self.logger.error(f"[回复合理评估] 回复合理评估失败: {str(e)}", exc_info=True)
            import traceback
            error_traceback = traceback.format_exc()
            self.logger.error(f"[回复合理评估] 错误堆栈:\n{error_traceback}")
            traceback.print_exc()
            
            # 🔥 修复：确保错误消息可以被安全编码
            error_msg = str(e)
            try:
                # 尝试编码为latin-1，如果失败则使用ASCII安全的版本
                error_msg.encode('latin-1')
            except UnicodeEncodeError:
                # 如果包含无法用latin-1编码的字符，使用ASCII安全的错误消息
                error_msg = repr(e)  # 使用repr会转义非ASCII字符
            
            self.send_json_response({
                'success': False,
                'error': error_msg,
                'error_type': type(e).__name__
            }, status_code=500)
    
    def save_reply_reasonable_statistics(self, statistics):
        """保存回复合理评估统计结果到SQLite数据库"""
        try:
            import sqlite3
            
            self.logger.info("[保存统计] 开始保存回复合理评估统计结果...")
            
            # 创建数据库目录
            db_dir = 'data'
            if not os.path.exists(db_dir):
                os.makedirs(db_dir)
            
            db_path = os.path.join(db_dir, 'reply_reasonable_statistics.db')
            self.logger.debug(f"[保存统计] 数据库路径: {db_path}")
            
            # 连接SQLite数据库
            conn = sqlite3.connect(db_path)
            cursor = conn.cursor()
            
            # 创建表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS reply_reasonable_statistics (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT,
                    total_pairs INTEGER,
                    evaluated_count INTEGER,
                    reasonable_count INTEGER,
                    unreasonable_count INTEGER,
                    failed_count INTEGER,
                    statistics_data TEXT
                )
            ''')
            
            # 插入统计数据
            insert_data = (
                statistics.get('timestamp', datetime.now().isoformat()),
                statistics.get('total_pairs', 0),
                statistics.get('evaluated_count', 0),
                statistics.get('reasonable_count', 0),
                statistics.get('unreasonable_count', 0),
                statistics.get('failed_count', 0),
                json.dumps(statistics, ensure_ascii=False)
            )
            
            cursor.execute('''
                INSERT INTO reply_reasonable_statistics 
                (timestamp, total_pairs, evaluated_count, reasonable_count, unreasonable_count, failed_count, statistics_data)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ''', insert_data)
            
            conn.commit()
            conn.close()
            
            self.logger.info(f"[保存统计] 回复合理评估统计结果已保存到: {os.path.abspath(db_path)}")
            
        except Exception as e:
            self.logger.error(f"[保存统计] 保存回复合理评估统计结果失败: {str(e)}", exc_info=True)
            raise
    
    def export_to_sqlite(self, evaluations):
        """导出评估结果到SQLite数据库"""
        import sqlite3
        
        try:
            self.logger.info(f"开始导出 {len(evaluations)} 条评估数据到SQLite...")
            
            # 创建数据库文件路径（添加时间戳）
            db_dir = 'exports'
            if not os.path.exists(db_dir):
                self.logger.debug(f"创建exports目录: {db_dir}")
                os.makedirs(db_dir)
            
            # 生成带时间戳的文件名
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            db_filename = f'salary_evaluations_{timestamp}.db'
            db_path = os.path.join(db_dir, db_filename)
            self.logger.debug(f"数据库路径: {db_path}")
            print(f"📝 数据库文件: {db_filename}")
            
            # 连接SQLite数据库
            self.logger.debug("连接到SQLite数据库...")
            conn = sqlite3.connect(db_path)
            cursor = conn.cursor()
            
            # 创建表
            self.logger.debug("创建数据库表...")
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS salary_evaluations (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    message_id INTEGER,
                    candidate_id INTEGER,
                    candidate_name TEXT,
                    content TEXT,
                    created_at TEXT,
                    is_salary_related INTEGER,
                    score INTEGER,
                    reason TEXT,
                    detected_keywords TEXT,
                    evaluation_timestamp TEXT
                )
            ''')
            
            # 创建索引
            self.logger.debug("创建数据库索引...")
            cursor.execute('CREATE INDEX IF NOT EXISTS idx_candidate_id ON salary_evaluations(candidate_id)')
            cursor.execute('CREATE INDEX IF NOT EXISTS idx_message_id ON salary_evaluations(message_id)')
            cursor.execute('CREATE INDEX IF NOT EXISTS idx_salary_related ON salary_evaluations(is_salary_related)')
            
            # 插入数据
            count = 0
            print(f"📥 开始插入 {len(evaluations)} 条数据...")
            
            for idx, eval_data in enumerate(evaluations):
                try:
                    self.logger.debug(f"处理第 {idx + 1} 条评估数据...")
                    
                    # 获取evaluation字段
                    evaluation = eval_data.get('evaluation', {})
                    self.logger.debug(f"评估数据键: {list(eval_data.keys())}")
                    self.logger.debug(f"evaluation键: {list(evaluation.keys()) if evaluation else 'None'}")
                    
                    # 准备插入数据
                    insert_data = (
                        eval_data.get('message_id'),
                        eval_data.get('candidate_id'),
                        eval_data.get('candidate_name'),
                        eval_data.get('content'),
                        eval_data.get('created_at'),
                        1 if evaluation.get('is_salary_related') else 0,
                        evaluation.get('score', 0),
                        evaluation.get('reason', ''),
                        json.dumps(evaluation.get('detected_keywords', []), ensure_ascii=False),
                        datetime.now().isoformat()
                    )
                    
                    self.logger.debug(f"插入数据: message_id={insert_data[0]}, candidate_id={insert_data[1]}, is_salary_related={insert_data[5]}")
                    
                    cursor.execute('''
                        INSERT INTO salary_evaluations 
                        (message_id, candidate_id, candidate_name, content, created_at, 
                         is_salary_related, score, reason, detected_keywords, evaluation_timestamp)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    ''', insert_data)
                    
                    count += 1
                    
                    # 每10条显示一次进度
                    if (idx + 1) % 10 == 0:
                        self.logger.debug(f"已插入 {idx + 1}/{len(evaluations)} 条数据")
                        print(f"  ... 已插入 {idx + 1}/{len(evaluations)} 条数据")
                        
                except Exception as e:
                    self.logger.error(f"插入第 {idx + 1} 条数据时出错: {str(e)}")
                    self.logger.error(f"数据内容: {json.dumps(eval_data, ensure_ascii=False)}")
                    raise
            
            self.logger.debug("提交事务...")
            conn.commit()
            conn.close()
            
            self.logger.info(f"成功导出 {count} 条数据到 {os.path.abspath(db_path)}")
            
            return {
                'count': count,
                'db_path': os.path.abspath(db_path)
            }
            
        except Exception as e:
            self.logger.error(f"导出到SQLite失败: {str(e)}", exc_info=True)
            raise
    
    def save_evaluation_statistics(self, statistics):
        """保存评估统计结果到SQLite数据库"""
        try:
            import sqlite3
            
            self.logger.info("[保存统计] 开始保存评估统计结果...")
            
            # 创建数据库目录
            db_dir = 'data'
            if not os.path.exists(db_dir):
                os.makedirs(db_dir)
            
            db_path = os.path.join(db_dir, 'evaluation_statistics.db')
            self.logger.debug(f"[保存统计] 数据库路径: {db_path}")
            
            # 连接SQLite数据库
            conn = sqlite3.connect(db_path)
            cursor = conn.cursor()
            
            # 创建表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS evaluation_statistics (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT,
                    total_candidates INTEGER,
                    total_messages INTEGER,
                    total_ai_messages INTEGER,
                    keyword_evaluated_count INTEGER,
                    evaluated_count INTEGER,
                    failed_count INTEGER,
                    pending_count INTEGER,
                    salary_messages_count INTEGER,
                    non_salary_messages_count INTEGER,
                    photo_messages_count INTEGER,
                    statistics_data TEXT
                )
            ''')
            
            # 检查并添加keyword_evaluated_count字段（兼容旧数据库）
            try:
                cursor.execute("SELECT keyword_evaluated_count FROM evaluation_statistics LIMIT 1")
            except sqlite3.OperationalError:
                self.logger.info("[保存统计] 数据库缺少keyword_evaluated_count字段，正在添加...")
                cursor.execute("ALTER TABLE evaluation_statistics ADD COLUMN keyword_evaluated_count INTEGER DEFAULT 0")
                conn.commit()
                self.logger.info("[保存统计] keyword_evaluated_count字段添加成功")
            
            # 插入统计数据
            keyword_count = statistics.get('keyword_evaluated_count', 0)
            self.logger.info(f"[保存统计] 准备保存keyword_evaluated_count: {keyword_count}")
            
            insert_data = (
                statistics.get('timestamp', datetime.now().isoformat()),
                statistics.get('total_candidates', 0),
                statistics.get('total_messages', 0),
                statistics.get('total_ai_messages', 0),
                keyword_count,  # 添加keyword_evaluated_count
                statistics.get('evaluated_count', 0),
                statistics.get('failed_count', 0),
                statistics.get('pending_count', 0),
                statistics.get('salary_messages_count', 0),
                statistics.get('non_salary_messages_count', 0),
                statistics.get('photo_messages_count', 0),
                json.dumps(statistics, ensure_ascii=False)
            )
            
            cursor.execute('''
                INSERT INTO evaluation_statistics 
                (timestamp, total_candidates, total_messages, total_ai_messages, 
                 keyword_evaluated_count, evaluated_count, failed_count, pending_count, 
                 salary_messages_count, non_salary_messages_count, photo_messages_count,
                 statistics_data)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', insert_data)
            
            conn.commit()
            conn.close()
            
            self.logger.info(f"[保存统计] 评估统计结果已保存到: {os.path.abspath(db_path)}")
            
        except Exception as e:
            self.logger.error(f"[保存统计] 保存评估统计结果失败: {str(e)}", exc_info=True)
            raise
    
    def handle_evaluation_statistics(self):
        """处理获取评估统计请求"""
        try:
            import sqlite3
            
            self.logger.info("========== [获取评估统计] 开始处理请求 ==========")
            
            # 从数据库获取最新的统计数据
            db_dir = 'data'
            db_path = os.path.join(db_dir, 'evaluation_statistics.db')
            self.logger.debug(f"[获取评估统计] 数据库路径: {db_path}")
            
            if not os.path.exists(db_path):
                # 数据库不存在，返回空数据
                response_data = {
                    'success': True,
                    'has_data': False,
                    'message': '暂无评估统计',
                    'timestamp': datetime.now().isoformat()
                }
                self.logger.info("[获取评估统计] 数据库不存在，返回空数据")
                self.logger.info(f"[获取评估统计] 返回数据: has_data=False")
            else:
                # 连接数据库并获取最新统计数据
                self.logger.debug(f"[获取评估统计] 连接数据库: {db_path}")
                conn = sqlite3.connect(db_path)
                cursor = conn.cursor()
                
                # 先检查表结构，确定是否有keyword_evaluated_count字段
                cursor.execute("PRAGMA table_info(evaluation_statistics)")
                columns = [col[1] for col in cursor.fetchall()]
                has_keyword_field = 'keyword_evaluated_count' in columns
                
                self.logger.debug(f"[获取评估统计] 数据库字段列表: {columns}")
                self.logger.debug(f"[获取评估统计] 是否包含keyword_evaluated_count: {has_keyword_field}")
                
                # 根据表结构选择查询语句
                if has_keyword_field:
                    # 新表结构：显式指定字段名
                    cursor.execute('''
                        SELECT timestamp, total_candidates, total_messages, total_ai_messages,
                               keyword_evaluated_count, evaluated_count, failed_count, pending_count,
                               salary_messages_count, non_salary_messages_count, photo_messages_count,
                               statistics_data
                        FROM evaluation_statistics 
                        ORDER BY timestamp DESC 
                        LIMIT 1
                    ''')
                else:
                    # 旧表结构：没有keyword_evaluated_count字段
                    cursor.execute('''
                        SELECT timestamp, total_candidates, total_messages, total_ai_messages,
                               evaluated_count, failed_count, pending_count,
                               salary_messages_count, non_salary_messages_count, photo_messages_count,
                               statistics_data
                        FROM evaluation_statistics 
                        ORDER BY timestamp DESC 
                        LIMIT 1
                    ''')
                
                row = cursor.fetchone()
                conn.close()
                
                if row:
                    self.logger.info(f"[获取评估统计] 找到统计数据，共 {len(row)} 个字段")
                    
                    # 根据表结构解析数据
                    if has_keyword_field:
                        # 新格式：包含keyword_evaluated_count
                        timestamp = row[0]
                        total_candidates = row[1]
                        total_messages = row[2]
                        total_ai_messages = row[3]
                        keyword_count = row[4]
                        evaluated_count = row[5]
                        failed_count = row[6]
                        pending_count = row[7]
                        salary_messages_count = row[8]
                        non_salary_messages_count = row[9]
                        photo_messages_count = row[10]
                        statistics_data = row[11]
                    else:
                        # 旧格式：不包含keyword_evaluated_count
                        timestamp = row[0]
                        total_candidates = row[1]
                        total_messages = row[2]
                        total_ai_messages = row[3]
                        keyword_count = 0  # 旧数据默认为0
                        evaluated_count = row[4]
                        failed_count = row[5]
                        pending_count = row[6]
                        salary_messages_count = row[7]
                        non_salary_messages_count = row[8]
                        photo_messages_count = row[9]
                        statistics_data = row[10]
                    
                    self.logger.info(f"[获取评估统计] 统计详情: 候选人数={total_candidates}, AI消息数={total_ai_messages}, 关键词评估={keyword_count}, 薪资消息={salary_messages_count}, 要照片消息={photo_messages_count}")
                    
                    # 返回详细统计数据
                    response_data = {
                        'success': True,
                        'has_data': True,
                        'timestamp': timestamp,
                        'total_candidates': total_candidates,
                        'total_messages': total_messages,
                        'total_ai_messages': total_ai_messages,
                        'keyword_evaluated_count': keyword_count,  # 添加关键词评估数量
                        'evaluated_count': evaluated_count,
                        'failed_count': failed_count,
                        'pending_count': pending_count,
                        'salary_messages_count': salary_messages_count,
                        'non_salary_messages_count': non_salary_messages_count,
                        'photo_messages_count': photo_messages_count,
                        'data': json.loads(statistics_data) if statistics_data else {}
                    }
                    self.logger.info(f"[获取评估统计] 成功获取统计数据，关键词评估: {keyword_count}, 薪资消息: {salary_messages_count}, 要照片消息: {photo_messages_count}")
                else:
                    # 数据库存在但没有数据
                    self.logger.info("[获取评估统计] 数据库存在但没有数据记录")
                    response_data = {
                        'success': True,
                        'has_data': False,
                        'message': '暂无评估统计',
                        'timestamp': datetime.now().isoformat()
                    }
            
            self.logger.info("[获取评估统计] 准备返回响应数据")
            
            # 返回结果
            self.send_json_response(response_data)
            self.logger.info("========== [获取评估统计] 请求处理完成 ==========")
            
        except Exception as e:
            self.logger.error(f"[获取评估统计] 获取评估统计失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': f"Failed to get evaluation statistics: {str(e)}"
            }, status_code=500)
    
    def handle_mysql_statistics(self):
        """处理获取MySQL实时统计请求"""
        try:
            self.logger.info("========== [MySQL实时统计] 开始处理请求 ==========")
            
            # 初始化monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[MySQL实时统计] Monitor未初始化，正在初始化...")
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                self.logger.info("[MySQL实时统计] Monitor初始化完成，连接数据库...")
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[MySQL实时统计] 数据库连接失败")
                    self.send_json_response({
                        'success': False,
                        'error': '数据库连接失败'
                    }, status_code=500)
                    return
                self.logger.info("[MySQL实时统计] 数据库连接成功")
            else:
                self.logger.info("[MySQL实时统计] Monitor已初始化")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            # 查询候选人总数
            self.logger.debug("[MySQL实时统计] 查询候选人总数...")
            monitor.cursor.execute("SELECT COUNT(*) as total FROM candidates")
            total_candidates = monitor.cursor.fetchone()['total']
            self.logger.info(f"[MySQL实时统计] 候选人总数: {total_candidates}")
            
            # 查询最近30天的候选人
            monitor.cursor.execute("""
                SELECT COUNT(*) as total 
                FROM candidates 
                WHERE updated_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
            """)
            recent_candidates = monitor.cursor.fetchone()['total']
            self.logger.info(f"[MySQL实时统计] 最近30天候选人: {recent_candidates}")
            
            # 查询消息总数
            monitor.cursor.execute("SELECT COUNT(*) as total FROM messages")
            total_messages = monitor.cursor.fetchone()['total']
            self.logger.info(f"[MySQL实时统计] 消息总数: {total_messages}")
            
            # 查询AI消息数
            monitor.cursor.execute("SELECT COUNT(*) as total FROM messages WHERE sender = '我'")
            ai_messages = monitor.cursor.fetchone()['total']
            self.logger.info(f"[MySQL实时统计] AI消息数: {ai_messages}")
            
            # 查询用户消息数
            monitor.cursor.execute("SELECT COUNT(*) as total FROM messages WHERE sender != '我'")
            user_messages = monitor.cursor.fetchone()['total']
            self.logger.info(f"[MySQL实时统计] 用户消息数: {user_messages}")
            
            # 构建响应数据
            response_data = {
                'success': True,
                'has_data': True,
                'timestamp': datetime.now().isoformat(),
                'total_candidates': total_candidates,
                'recent_candidates': recent_candidates,
                'total_messages': total_messages,
                'ai_messages': ai_messages,
                'user_messages': user_messages,
                'database_info': {
                    'host': DB_CONFIG.get('host', 'unknown'),
                    'database': DB_CONFIG.get('database', 'unknown'),
                    'connected': True
                }
            }
            
            self.logger.info(f"[MySQL实时统计] 返回统计结果: 候选人={total_candidates}, AI消息={ai_messages}")
            self.send_json_response(response_data)
            self.logger.info("========== [MySQL实时统计] 请求处理完成 ==========")
            
        except Exception as e:
            self.logger.error(f"[MySQL实时统计] 获取统计失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': f"Failed to get MySQL statistics: {str(e)}"
            }, status_code=500)
    
    def handle_get_prompt(self, query_params):
        """处理获取提示词请求"""
        try:
            self.logger.info("========== [获取提示词] 开始处理请求 ==========")
            
            category = query_params.get('category', ['reply_reasonable'])[0]
            self.logger.info(f"[获取提示词] 类别: {category}")
            
            # 返回当前使用的提示词
            if EnhancedHTTPRequestHandler.current_prompt:
                response_data = {
                    'success': True,
                    'category': category,
                    'prompt': EnhancedHTTPRequestHandler.current_prompt,
                    'source': 'server'
                }
                self.logger.info("[获取提示词] 返回服务器当前提示词")
            else:
                # 使用默认提示词（参考客服话术标准优化版）
                default_prompt = """你是一个专业的AI智能客服对话质量评估专家，专门评估招聘直播主播岗位的客服回复质量。

## 背景信息
这是一个招聘直播主播岗位的客服系统（可能通过Boss直聘等平台招聘）。
- **工作性质**：视频露脸直播主播（纯聊天类型，不需要才艺）
- **平台**：B站（日结保底133元）或抖音（月结5000-8000元）
- **薪资模式**：日结保底 + 礼物提成（30%-51%）
- **工作地点**：居家线上直播，兼职全职都可以

## 关键评估标准（参考客服话术标准）

### 1. **信息准确性（权重：35%）**
**重点检查：**
- 薪资信息是否准确：日结保底133元（兼职4小时）或220元（全职6小时）
- 是否提供了具体数字而不是模糊描述
- 是否说明了具体发放时间
- 是否准确说明了提成比例和工作时间要求

### 2. **回复相关性（权重：25%）**
**重点检查：**
- 是否直接回答了用户的问题
- 是否理解用户意图

### 3. **专业性（权重：20%）**
**重点检查：**
- 是否使用了专业的招聘术语
- 是否避免了过度口语化
- 是否避免了欺骗性语言

### 4. **服务态度（权重：15%）**
- 语气是否友好、耐心
- 是否主动解答用户疑问

### 5. **合法合规性（权重：5%）**
- 是否涉及不当要求
- 是否避免了欺诈性承诺

请给出详细的评估结果和理由。"""
                
                response_data = {
                    'success': True,
                    'category': category,
                    'prompt': default_prompt,
                    'source': 'default'
                }
                self.logger.info("[获取提示词] 返回默认提示词")
            
            # 🔥 增强日志：记录current_prompt的状态
            if EnhancedHTTPRequestHandler.current_prompt:
                self.logger.info(f"[获取提示词] ✅ 返回服务器当前提示词")
                self.logger.info(f"[获取提示词] current_prompt长度: {len(EnhancedHTTPRequestHandler.current_prompt)}")
                self.logger.debug(f"[获取提示词] current_prompt预览（前200字符）: {EnhancedHTTPRequestHandler.current_prompt[:200]}...")
            else:
                self.logger.info(f"[获取提示词] ⚠️ current_prompt为空，返回默认提示词")
            
            self.logger.info(f"[获取提示词] 提示词长度: {len(response_data['prompt'])}")
            self.logger.info(f"[获取提示词] 提示词来源: {response_data.get('source', 'unknown')}")
            self.logger.info("========== [获取提示词] 请求处理完成 ==========")
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"[获取提示词] 获取提示词失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_update_prompt_post(self, data):
        """处理更新提示词POST请求"""
        try:
            self.logger.info("========== [更新提示词] 开始处理请求 ==========")
            
            prompt = data.get('prompt', '')
            category = data.get('category', 'reply_reasonable')
            
            self.logger.info(f"[更新提示词] 类别: {category}")
            self.logger.info(f"[更新提示词] 提示词长度: {len(prompt)}")
            self.logger.debug(f"[更新提示词] 提示词预览: {prompt[:200]}...")
            
            if not prompt:
                self.send_json_response({
                    'success': False,
                    'error': '提示词不能为空'
                }, status_code=400)
                return
            
            # 更新当前提示词
            EnhancedHTTPRequestHandler.current_prompt = prompt
            self.logger.info("[更新提示词] 提示词已更新到服务器")
            
            # 持久化保存提示词到文件
            try:
                import json
                prompt_file = f'data/{category}_prompt.json'
                os.makedirs('data', exist_ok=True)
                
                prompt_data = {
                    'prompt': prompt,
                    'category': category,
                    'updated_at': datetime.now().isoformat()
                }
                
                with open(prompt_file, 'w', encoding='utf-8') as f:
                    json.dump(prompt_data, f, ensure_ascii=False, indent=2)
                
                self.logger.info(f"[更新提示词] 提示词已保存到文件: {prompt_file}")
                
            except Exception as save_error:
                self.logger.error(f"[更新提示词] 保存提示词到文件失败: {str(save_error)}")
                # 不影响主流程，继续返回成功
            
            response_data = {
                'success': True,
                'category': category,
                'message': '提示词已更新并保存',
                'timestamp': datetime.now().isoformat()
            }
            
            self.logger.info("========== [更新提示词] 请求处理完成 ==========")
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"[更新提示词] 更新提示词失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_get_feedback_history(self, query_params):
        """处理获取评估历史记录请求"""
        try:
            import sqlite3
            
            self.logger.info("========== [获取评估历史] 开始处理请求 ==========")
            
            # 获取pair_id
            pair_id = query_params.get('pair_id', [''])[0]
            if not pair_id:
                self.logger.error("[获取评估历史] pair_id缺失")
                self.send_json_response({
                    'success': False,
                    'error': 'pair_id is required'
                }, status_code=400)
                return
            
            self.logger.info(f"[获取评估历史] 查询pair_id: {pair_id}")
            
            # 从数据库获取评估历史
            db_dir = 'data'
            db_path = os.path.join(db_dir, 'user_feedback.db')
            
            if not os.path.exists(db_path):
                self.logger.info("[获取评估历史] 数据库不存在，返回空历史")
                self.send_json_response({
                    'success': True,
                    'history': []
                })
                return
            
            # 连接数据库
            self.logger.debug(f"[获取评估历史] 连接数据库: {db_path}")
            conn = sqlite3.connect(db_path)
            cursor = conn.cursor()
            
            # 查询评估历史
            cursor.execute('''
                SELECT * FROM user_feedback 
                WHERE pair_id = ?
                ORDER BY feedback_timestamp DESC
            ''', (int(pair_id),))
            
            rows = cursor.fetchall()
            column_names = [desc[0] for desc in cursor.description]
            conn.close()

            history = [dict(zip(column_names, row)) for row in rows]
            self.logger.info(f"[获取评估历史] 找到 {len(history)} 条记录")

            limit_param = query_params.get('limit', [None])[0]
            history_result = self.prepare_feedback_history(history, limit=limit_param, logger=self.logger)

            response_data = {
                'success': True,
                'latest_record': history_result['latest_record'],
                'history': history_result['history_records'],
                'has_more_history': history_result['has_more_history'],
                'total_records': len(history),
                'applied_limit': history_result['applied_limit'],
            }

            self.logger.info(
                "[获取评估历史] 返回最新记录与历史列表 最新ID=%s 历史条数=%s 总计=%s limit=%s",
                response_data['latest_record'].get('id') if response_data['latest_record'] else None,
                len(response_data['history']),
                response_data['total_records'],
                response_data['applied_limit'],
            )
            self.logger.info("========== [获取评估历史] 请求处理完成 ==========")
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"[获取评估历史] 获取评估历史失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_reply_reasonable_statistics(self):
        """处理获取回复合理评估统计请求"""
        try:
            import sqlite3
            
            self.logger.info("========== [获取回复合理评估统计] 开始处理请求 ==========")
            
            # 从数据库获取最新的统计数据
            db_dir = 'data'
            db_path = os.path.join(db_dir, 'reply_reasonable_statistics.db')
            self.logger.debug(f"[获取回复合理评估统计] 数据库路径: {db_path}")
            
            if not os.path.exists(db_path):
                # 数据库不存在，返回空数据
                response_data = {
                    'success': True,
                    'has_data': False,
                    'message': '暂无评估统计',
                    'timestamp': datetime.now().isoformat()
                }
                self.logger.info("[获取回复合理评估统计] 数据库不存在，返回空数据")
                self.logger.info(f"[获取回复合理评估统计] 返回数据: has_data=False")
            else:
                # 连接数据库并获取最新统计数据
                self.logger.debug(f"[获取回复合理评估统计] 连接数据库: {db_path}")
                conn = sqlite3.connect(db_path)
                cursor = conn.cursor()
                
                cursor.execute('''
                    SELECT * FROM reply_reasonable_statistics 
                    ORDER BY timestamp DESC 
                    LIMIT 1
                ''')
                
                row = cursor.fetchone()
                conn.close()
                
                if row:
                    self.logger.info(f"[获取回复合理评估统计] 找到统计数据，共 {len(row)} 个字段")
                    self.logger.debug(f"[获取回复合理评估统计] 统计详情: 消息对数={row[2]}, 合理回复={row[4]}, 不合理回复={row[5]}")
                    
                    # 返回详细统计数据
                    response_data = {
                        'success': True,
                        'has_data': True,
                        'timestamp': row[1],
                        'total_pairs': row[2],
                        'evaluated_count': row[3],
                        'reasonable_count': row[4],
                        'unreasonable_count': row[5],
                        'failed_count': row[6],
                        'data': json.loads(row[7]) if row[7] else {}
                    }
                    self.logger.info(f"[获取回复合理评估统计] 成功获取统计数据，合理回复: {row[4]}, 不合理回复: {row[5]}")
                else:
                    # 数据库存在但没有数据
                    self.logger.info("[获取回复合理评估统计] 数据库存在但没有数据记录")
                    response_data = {
                        'success': True,
                        'has_data': False,
                        'message': '暂无评估统计',
                        'timestamp': datetime.now().isoformat()
                    }
            
            self.logger.info("[获取回复合理评估统计] 准备返回响应数据")
            
            # 返回结果
            self.send_json_response(response_data)
            self.logger.info("========== [获取回复合理评估统计] 请求处理完成 ==========")
            
        except Exception as e:
            self.logger.error(f"[获取回复合理评估统计] 获取回复合理评估统计失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': f"Failed to get reply reasonable statistics: {str(e)}"
            }, status_code=500)
    
    def handle_save_feedback_post(self, data):
        """处理保存用户反馈POST请求"""
        self.logger.info("=" * 80)
        self.logger.info("[用户反馈] ========== 收到保存用户反馈POST请求 ==========")
        try:
            # 安全地序列化数据进行日志记录
            try:
                data_str = json.dumps(data, ensure_ascii=False, indent=2)
                self.logger.debug(f"[用户反馈] 接收到的完整数据:\n{data_str}")
            except Exception as e:
                self.logger.warning(f"[用户反馈] 无法序列化完整数据: {str(e)}")
                self.logger.debug(f"[用户反馈] 数据类型: {type(data)}")
                if isinstance(data, dict):
                    self.logger.debug(f"[用户反馈] 数据键: {list(data.keys())}")
            
            self.logger.info("[用户反馈] 开始处理反馈请求")
            
            # 获取反馈数据
            self.logger.info("[用户反馈] 开始解析数据字段...")
            
            def safe_get(key, default=''):
                """安全获取字段，确保字符串类型"""
                value = data.get(key, default)
                if isinstance(value, str):
                    return value
                else:
                    return str(value) if value else default
            
            pair_id = data.get('pair_id')
            original_label = safe_get('original_label', '')
            new_label = safe_get('new_label', '')
            user_feedback = safe_get('user_feedback', '')
            user_message = safe_get('user_message', '')
            ai_reply = safe_get('ai_reply', '')
            evaluation_reason = safe_get('evaluation_reason', '')
            
            self.logger.info(f"[用户反馈] pair_id: {pair_id}")
            self.logger.info(f"[用户反馈] original_label: {original_label[:50]}...")
            self.logger.info(f"[用户反馈] new_label: {new_label[:50]}...")
            self.logger.info(f"[用户反馈] user_feedback长度: {len(user_feedback)}")
            self.logger.info(f"[用户反馈] user_message长度: {len(user_message)}")
            self.logger.info(f"[用户反馈] ai_reply长度: {len(ai_reply)}")
            
            # 验证必要字段
            if not pair_id:
                self.logger.error("[用户反馈] pair_id缺失")
                self.send_json_response({
                    'success': False,
                    'error': 'pair_id is required'
                }, status_code=400)
                return
            
            self.logger.info(f"[用户反馈] 处理反馈 - pair_id: {pair_id}, 原始标签: {original_label}, 新标签: {new_label}")
            
            # 根据用户反馈重新评估信息对
            self.logger.info("=" * 80)
            self.logger.info("[用户反馈] ========== 开始根据用户反馈重新评估 ==========")
            
            # 初始化Monitor（如果还未初始化）
            if not EnhancedHTTPRequestHandler.monitor:
                self.logger.warning("[用户反馈] Monitor未初始化，正在初始化...")
                try:
                    EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                    self.logger.info("[用户反馈] Monitor初始化完成，连接数据库...")
                    if not EnhancedHTTPRequestHandler.monitor.connect_db():
                        self.logger.error("[用户反馈] 数据库连接失败")
                        self.send_json_response({
                            'success': False,
                            'error': '数据库连接失败'
                        }, status_code=500)
                        return
                    self.logger.info("[用户反馈] 数据库连接成功")
                except Exception as e:
                    self.logger.error(f"[用户反馈] Monitor初始化失败: {str(e)}", exc_info=True)
                    self.send_json_response({
                        'success': False,
                        'error': f'Monitor初始化失败: {str(e)}'
                    }, status_code=500)
                    return
            else:
                self.logger.info("[用户反馈] Monitor已初始化")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            if not monitor.ai_enabled:
                self.logger.error("[用户反馈] AI评估功能未启用")
                self.send_json_response({
                    'success': False,
                    'error': 'AI评估功能未启用'
                }, status_code=503)
                return
            
            # 根据用户反馈重新评估
            self.logger.info("=" * 80)
            self.logger.info("[用户反馈] ========== 开始AI重新评估流程 ==========")
            self.logger.info(f"[用户反馈] 用户消息长度: {len(user_message)} 字符")
            self.logger.info(f"[用户反馈] 用户消息前100字符: {user_message[:100]}")
            self.logger.info(f"[用户反馈] AI回复长度: {len(ai_reply)} 字符")
            self.logger.info(f"[用户反馈] AI回复前100字符: {ai_reply[:100]}")
            self.logger.info(f"[用户反馈] 用户反馈: {user_feedback}")
            self.logger.info(f"[用户反馈] 原始标签: {original_label}")
            self.logger.info(f"[用户反馈] 新标签: {new_label}")
            
            # 构建用户反馈文本（如果没有提供反馈，使用标签修改）
            feedback_text = user_feedback
            if not feedback_text:
                feedback_text = f"用户认为原始标签'{original_label}'不正确，应该为'{new_label}'"
            
            self.logger.info(f"[用户反馈] 构建的反馈文本: {feedback_text}")
            self.logger.info("[用户反馈] 准备调用evaluate_reply_reasonable_with_feedback方法...")
            
            # 检查是否有更新的提示词
            custom_prompt = data.get('custom_prompt', None)
            
            # 🔥 增强日志：明确记录各种触发条件
            has_label_change = original_label != new_label
            has_feedback = bool(user_feedback and user_feedback.strip())
            has_custom_prompt = bool(custom_prompt)
            
            self.logger.info(f"[用户反馈] ========== 分析保存反馈的触发条件 ==========")
            self.logger.info(f"[用户反馈] 1. 标签是否修改: {has_label_change} ('{original_label}' -> '{new_label}')")
            self.logger.info(f"[用户反馈] 2. 是否有用户建议: {has_feedback} (长度: {len(user_feedback) if user_feedback else 0})")
            self.logger.info(f"[用户反馈] 3. 是否有自定义提示词: {has_custom_prompt} (长度: {len(custom_prompt) if custom_prompt else 0})")
            
            # 确定评估路径
            if has_custom_prompt:
                evaluation_path = "使用自定义提示词评估"
            elif has_feedback and len(user_feedback.strip()) > 20:
                evaluation_path = "生成改进提示词并评估"
            elif has_label_change or has_feedback:
                evaluation_path = "基于标签修改或简短建议评估"
            else:
                evaluation_path = "无有效修改"
            
            self.logger.info(f"[用户反馈] 评估路径: {evaluation_path}")
            print(f"[用户反馈] 📋 评估路径: {evaluation_path}")
            print(f"[用户反馈] 🔍 触发条件分析:")
            print(f"[用户反馈] - 标签修改: {has_label_change}")
            print(f"[用户反馈] - 用户建议: {has_feedback} (长度: {len(user_feedback) if user_feedback else 0})")
            print(f"[用户反馈] - 自定义提示词: {has_custom_prompt} (长度: {len(custom_prompt) if custom_prompt else 0})")
            
            if not (has_label_change or has_feedback or has_custom_prompt):
                self.logger.error("[用户反馈] ❌ 没有任何有效修改，拒绝处理")
                print("[用户反馈] ❌ 没有任何有效修改，拒绝处理")
                self.send_json_response({
                    'success': False,
                    'error': '请至少修改标签、提供建议或修改提示词'
                }, status_code=400)
                return
            
            # 如果提供了自定义提示词，使用它进行重新评估
            if custom_prompt:
                self.logger.info("[用户反馈] ========== 使用自定义提示词进行重新评估 ==========")
                self.logger.info(f"[用户反馈] 自定义提示词长度: {len(custom_prompt)}")
                self.logger.debug(f"[用户反馈] 自定义提示词预览: {custom_prompt[:200]}...")
                
                # 获取更新前的提示词状态
                old_prompt_length = len(EnhancedHTTPRequestHandler.current_prompt) if EnhancedHTTPRequestHandler.current_prompt else 0
                self.logger.info(f"[用户反馈] 更新前current_prompt长度: {old_prompt_length}")
                
                # 使用DeepSeekEvaluator的evaluate_with_custom_prompt方法
                new_evaluation = monitor.salary_analyzer.evaluator.evaluate_with_custom_prompt(
                    user_message,
                    ai_reply,
                    custom_prompt
                )
                self.logger.info(f"[用户反馈] 自定义提示词评估完成")
                
                # 🔥 关键修复：同步更新current_prompt，确保后续评估使用最新的提示词
                self.logger.info("[用户反馈] ========== 同步更新current_prompt ==========")
                sync_result = sync_current_prompt(
                    EnhancedHTTPRequestHandler,
                    custom_prompt,
                    self.logger,
                    source="用户反馈-自定义提示词",
                    context={
                        'pair_id': pair_id,
                        'has_user_feedback': bool(user_feedback.strip()),
                        'label_changed': original_label != new_label,
                    },
                )
                print(
                    f"[用户反馈] ✅ 提示词已同步更新 (长度: {sync_result['old_length']} -> {sync_result['new_length']})"
                )
            else:
                # 如果用户提供了详细反馈，尝试优化提示词
                improved_prompt = None
                print(f"[用户反馈] 🔍 检查用户反馈条件...")
                print(f"[用户反馈] - user_feedback存在: {user_feedback is not None}")
                print(f"[用户反馈] - user_feedback长度: {len(user_feedback) if user_feedback else 0}")
                print(f"[用户反馈] - user_feedback.strip()长度: {len(user_feedback.strip()) if user_feedback else 0}")
                print(f"[用户反馈] - 是否大于20字符: {len(user_feedback.strip()) > 20 if user_feedback else False}")
                
                # 🔥 构建反馈文本：如果有用户反馈则使用，否则基于标签修改构建反馈
                # 注意：到达这里说明至少有标签修改或用户反馈（已在前面验证）
                optimization_feedback = user_feedback
                if not optimization_feedback or len(optimization_feedback.strip()) == 0:
                    # 如果没有用户反馈，使用标签修改构建反馈
                    optimization_feedback = f"用户认为原始评估标签'{original_label}'不正确，应该为'{new_label}'。请根据这个反馈调整评估标准。"
                    self.logger.info(f"[用户反馈] 基于标签修改构建反馈: {optimization_feedback}")
                
                # 只要有反馈或标签修改，就生成改进的提示词
                self.logger.info(f"[用户反馈] ========== 开始提示词优化流程 ==========")
                self.logger.info(f"[用户反馈] 优化反馈内容: {optimization_feedback}")
                print(f"[用户反馈] 🔄 开始生成改进的提示词，反馈内容: {optimization_feedback[:100]}...")
                
                # 获取当前使用的提示词
                current_prompt = EnhancedHTTPRequestHandler.current_prompt
                if not current_prompt:
                    # 使用默认提示词
                    self.logger.info("[用户反馈] current_prompt为空，使用默认提示词")
                    current_prompt = """你是一个专业的AI智能客服对话质量评估专家，专门评估招聘直播主播岗位的客服回复质量。

## 背景信息
这是一个招聘直播主播岗位的客服系统。
- **工作性质**：视频露脸直播主播（纯聊天类型，不需要才艺）
- **平台**：B站（日结保底133元）或抖音（月结5000-8000元）
- **薪资模式**：日结保底 + 礼物提成（30%-51%）

## 关键评估标准
1. **信息准确性（权重：35%）**：薪资信息是否准确，是否提供了具体数字
2. **回复相关性（权重：25%）**：是否直接回答了用户问题
3. **专业性（权重：20%）**：是否避免过度口语化和欺骗性语言
4. **服务态度（权重：15%）**：语气是否友好、耐心
5. **合法合规性（权重：5%）**：是否避免欺诈性承诺

请给出详细的评估结果和理由。"""
                else:
                    self.logger.info(f"[用户反馈] 使用current_prompt，长度: {len(current_prompt)}")
                
                # 步骤1：生成改进的提示词
                print("[用户反馈] 🔄 步骤1: 开始调用generate_improved_prompt生成改进的提示词")
                self.logger.info("[用户反馈] ========== 步骤1: 生成改进的提示词 ==========")
                improved_prompt = None
                try:
                    improved_prompt = monitor.salary_analyzer.evaluator.generate_improved_prompt(
                        optimization_feedback,  # 🔥 使用优化后的反馈文本
                        current_prompt
                    )
                    
                    if improved_prompt and len(improved_prompt.strip()) > 0:
                        print(f"[用户反馈] ✅ 成功生成改进的提示词，长度: {len(improved_prompt)}")
                        self.logger.info(f"[用户反馈] ✅ 成功生成改进的提示词，长度: {len(improved_prompt)}")
                        self.logger.debug(f"[用户反馈] 改进后的提示词预览（前500字符）: {improved_prompt[:500]}...")
                    else:
                        self.logger.warning("[用户反馈] ⚠️ 生成改进提示词返回为空或空字符串")
                        print("[用户反馈] ⚠️ 生成改进提示词返回为空")
                        improved_prompt = None
                except Exception as e:
                    print(f"[用户反馈] ❌ 生成改进提示词失败: {str(e)}")
                    self.logger.error(f"[用户反馈] ❌ 生成改进提示词失败: {str(e)}", exc_info=True)
                    improved_prompt = None
                
                # 如果生成了改进的提示词，使用它进行评估
                if improved_prompt:
                    print("[用户反馈] ========== 使用改进的提示词进行重新评估 ==========")
                    self.logger.info("[用户反馈] ========== 使用改进的提示词进行重新评估 ==========")
                    self.logger.info(f"[用户反馈] 改进提示词长度: {len(improved_prompt)}")
                    self.logger.debug(f"[用户反馈] 改进提示词预览: {improved_prompt[:200]}...")
                    
                    # 获取更新前的提示词状态
                    old_prompt_length = len(EnhancedHTTPRequestHandler.current_prompt) if EnhancedHTTPRequestHandler.current_prompt else 0
                    self.logger.info(f"[用户反馈] 更新前current_prompt长度: {old_prompt_length}")
                    
                    new_evaluation = monitor.salary_analyzer.evaluator.evaluate_with_custom_prompt(
                        user_message,
                        ai_reply,
                        improved_prompt
                    )
                    print(f"[用户反馈] ✅ 使用改进提示词评估完成，评分: {new_evaluation.get('score', 0)}")
                    self.logger.info(f"[用户反馈] 使用改进提示词评估完成")
                    
                    # 🔥 关键修复：同步更新current_prompt，确保后续评估使用最新的提示词
                    self.logger.info("[用户反馈] ========== 步骤3: 同步更新current_prompt ==========")
                    print("[用户反馈] 🔄 步骤3: 同步更新current_prompt")
                    
                    # 记录更新前状态
                    old_prompt_preview = EnhancedHTTPRequestHandler.current_prompt[:100] if EnhancedHTTPRequestHandler.current_prompt else "(空)"
                    self.logger.info(f"[用户反馈] 更新前current_prompt预览: {old_prompt_preview}...")
                    
                    # 更新current_prompt
                    sync_result = sync_current_prompt(
                        EnhancedHTTPRequestHandler,
                        improved_prompt,
                        self.logger,
                        source="用户反馈-改进提示词",
                        context={
                            'pair_id': pair_id,
                            'has_user_feedback': bool(user_feedback.strip()),
                            'label_changed': original_label != new_label,
                        },
                    )
                    new_prompt_preview = (
                        EnhancedHTTPRequestHandler.current_prompt[:100]
                        if EnhancedHTTPRequestHandler.current_prompt
                        else "(空)"
                    )
                    self.logger.info(f"[用户反馈] 更新后current_prompt预览: {new_prompt_preview}...")
                    print(
                        f"[用户反馈] ✅ 提示词已同步更新 (长度: {sync_result['old_length']} -> {sync_result['new_length']})"
                    )
                else:
                    # 🔥 修复：不应该走到这里，因为只要有反馈就应该生成改进的提示词
                    # 如果走到这里说明生成改进提示词失败，返回错误
                    error_msg = "无法生成改进的提示词，无法继续评估。请检查AI API是否正常。"
                    self.logger.error(f"[用户反馈] ❌ {error_msg}")
                    print(f"[用户反馈] ❌ {error_msg}")
                    self.send_json_response({
                        'success': False,
                        'error': error_msg
                    }, status_code=500)
                    return
            
            self.logger.info("=" * 80)
            self.logger.info("[用户反馈] ========== AI重新评估完成 ==========")
            self.logger.info(f"[用户反馈] 新评分: {new_evaluation.get('score', 0)}")
            self.logger.info(f"[用户反馈] 新标签: {new_evaluation.get('is_reasonable', False)} ({'合理' if new_evaluation.get('is_reasonable', False) else '不合理'})")
            self.logger.info(f"[用户反馈] 是否采纳用户反馈: {new_evaluation.get('user_feedback_adopted', False)}")
            self.logger.info(f"[用户反馈] 反馈解释: {new_evaluation.get('feedback_explanation', '')}")
            self.logger.debug(f"[用户反馈] 完整评估结果: {json.dumps(new_evaluation, ensure_ascii=False, indent=2)}")
            self.logger.info("=" * 80)
            
            # 保存反馈到SQLite数据库
            self.logger.info("=" * 80)
            self.logger.info("[用户反馈] ========== 开始保存反馈到数据库 ==========")
            try:
                import sqlite3
                
                db_dir = 'data'
                if not os.path.exists(db_dir):
                    self.logger.debug(f"[用户反馈] 创建data目录: {db_dir}")
                    os.makedirs(db_dir)
                
                db_path = os.path.join(db_dir, 'user_feedback.db')
                self.logger.info(f"[用户反馈] 数据库路径: {db_path}")
                
                self.logger.debug("[用户反馈] 连接到SQLite数据库...")
                conn = sqlite3.connect(db_path)
                cursor = conn.cursor()
                
                # 创建表
                self.logger.debug("[用户反馈] 创建user_feedback表...")
                cursor.execute('''
                    CREATE TABLE IF NOT EXISTS user_feedback (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        pair_id INTEGER,
                        original_label TEXT,
                        new_label TEXT,
                        user_feedback TEXT,
                        user_message TEXT,
                        ai_reply TEXT,
                        evaluation_reason TEXT,
                        feedback_timestamp TEXT,
                        changed INTEGER DEFAULT 0,
                        new_score INTEGER,
                        new_is_reasonable INTEGER,
                        feedback_adopted INTEGER,
                        feedback_explanation TEXT
                    )
                ''')
                
                # 插入反馈数据和新的评估结果
                insert_data = (
                    pair_id,
                    original_label,
                    new_label,
                    user_feedback,
                    user_message,
                    ai_reply,
                    evaluation_reason,
                    datetime.now().isoformat(),
                    1 if new_label != original_label else 0,
                    new_evaluation.get('score', 0),
                    1 if new_evaluation.get('is_reasonable', False) else 0,
                    1 if new_evaluation.get('user_feedback_adopted', False) else 0,
                    new_evaluation.get('feedback_explanation', '')
                )
                
                self.logger.info(f"[用户反馈] 准备插入数据 - pair_id: {insert_data[0]}, changed: {insert_data[8]}")
                self.logger.debug(f"[用户反馈] 插入数据详情: original_label={insert_data[1]}, new_label={insert_data[2]}, score={insert_data[9]}")
                
                cursor.execute('''
                    INSERT INTO user_feedback 
                    (pair_id, original_label, new_label, user_feedback, user_message, ai_reply, evaluation_reason, feedback_timestamp, changed, new_score, new_is_reasonable, feedback_adopted, feedback_explanation)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                ''', insert_data)
                
                self.logger.debug("[用户反馈] 提交事务...")
                conn.commit()
                conn.close()
                
                self.logger.info(f"[用户反馈] 反馈已保存到: {os.path.abspath(db_path)}")
                self.logger.info("[用户反馈] ========== 数据库保存完成 ==========")
                self.logger.info("=" * 80)
                
                # 🔥 关键修复：更新reply_reasonable_statistics数据库中的统计数据
                self.logger.info("=" * 80)
                self.logger.info("[用户反馈] ========== 开始更新统计数据库 ==========")
                try:
                    # 构建新的评估数据
                    evaluation_payload = {
                        'score': new_evaluation.get('score', 0),
                        'is_reasonable': new_evaluation.get('is_reasonable', False),
                        'reason': new_evaluation.get('reason', ''),
                        'strengths': new_evaluation.get('strengths', []),
                        'weaknesses': new_evaluation.get('weaknesses', []),
                        'user_feedback_adopted': new_evaluation.get('user_feedback_adopted', False),
                        'feedback_explanation': new_evaluation.get('feedback_explanation', ''),
                        'success': True
                    }
                    
                    self.logger.info(f"[用户反馈] 准备更新统计 - pair_id: {pair_id}")
                    self.logger.info(f"[用户反馈] 新评估结果 - is_reasonable: {evaluation_payload['is_reasonable']}, score: {evaluation_payload['score']}")
                    
                    # 调用更新统计方法
                    update_success = EnhancedHTTPRequestHandler.update_statistics_after_feedback(
                        pair_id=pair_id,
                        evaluation_payload=evaluation_payload,
                        logger=self.logger
                    )
                    
                    if update_success:
                        self.logger.info("[用户反馈] ✅ 统计数据库更新成功")
                        print(f"[用户反馈] ✅ 统计数据库已更新 - pair_id: {pair_id}, is_reasonable: {evaluation_payload['is_reasonable']}")
                    else:
                        self.logger.warning("[用户反馈] ⚠️ 统计数据库更新失败或未找到对应记录")
                        print(f"[用户反馈] ⚠️ 统计数据库更新失败 - pair_id: {pair_id}")
                        
                except Exception as e:
                    self.logger.error(f"[用户反馈] 更新统计数据库时发生错误: {str(e)}", exc_info=True)
                    print(f"[用户反馈] ❌ 更新统计数据库失败: {str(e)}")
                    # 不影响主流程，继续返回成功响应
                
                self.logger.info("[用户反馈] ========== 统计数据库更新完成 ==========")
                self.logger.info("=" * 80)
                
                # 返回新的评估结果
                response_data = {
                    'success': True,
                    'message': '反馈已保存并重新评估',
                    'pair_id': pair_id,
                    'original_label': original_label,
                    'new_label': new_label,
                    'timestamp': datetime.now().isoformat(),
                    'new_evaluation': {
                        'score': new_evaluation.get('score', 0),
                        'is_reasonable': new_evaluation.get('is_reasonable', False),
                        'reason': new_evaluation.get('reason', ''),
                        'strengths': new_evaluation.get('strengths', []),
                        'weaknesses': new_evaluation.get('weaknesses', []),
                        'user_feedback_adopted': new_evaluation.get('user_feedback_adopted', False),
                        'feedback_explanation': new_evaluation.get('feedback_explanation', '')
                    }
                }
                
                self.send_json_response(response_data)
                
            except Exception as e:
                self.logger.error(f"[用户反馈] 保存反馈失败: {str(e)}", exc_info=True)
                self.send_json_response({
                    'success': False,
                    'error': f"Failed to save feedback: {str(e)}"
                }, status_code=500)
                
        except Exception as e:
            self.logger.error(f"[用户反馈] 处理反馈请求失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': str(e)
            }, status_code=500)
    
    def handle_candidate_messages(self, query_params):
        """处理获取候选人聊天记录请求"""
        try:
            self.logger.info("=" * 80)
            self.logger.info("[获取聊天记录] ========== 开始处理请求 ==========")
            
            # 获取候选人ID参数
            candidate_id = query_params.get('candidate_id', [None])[0]
            self.logger.debug(f"[获取聊天记录] 接收到的candidate_id参数: {candidate_id}")
            
            if not candidate_id:
                self.logger.warning("[获取聊天记录] 缺少candidate_id参数")
                self.send_json_response({
                    'success': False,
                    'error': '缺少candidate_id参数'
                }, status_code=400)
                return
            
            # 转换为整数
            try:
                candidate_id = int(candidate_id)
                self.logger.info(f"[获取聊天记录] 候选人ID: {candidate_id}")
            except ValueError:
                self.logger.error(f"[获取聊天记录] 无效的candidate_id: {candidate_id}")
                self.send_json_response({
                    'success': False,
                    'error': '无效的candidate_id参数'
                }, status_code=400)
                return
            
            # 获取可选参数
            limit = int(query_params.get('limit', [100])[0])
            message_type = query_params.get('type', [None])[0]
            self.logger.debug(f"[获取聊天记录] 消息条数限制: {limit}, 消息类型: {message_type}")
            
            # 初始化Monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[获取聊天记录] Monitor未初始化，正在初始化...")
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[获取聊天记录] 数据库连接失败")
                    self.send_json_response({
                        'success': False,
                        'error': '数据库连接失败'
                    }, status_code=500)
                    return
                self.logger.info("[获取聊天记录] Monitor初始化成功")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            # 获取聊天记录
            self.logger.info(f"[获取聊天记录] 正在查询候选人 {candidate_id} 的聊天记录...")
            result = monitor.get_user_chat_records(candidate_id, limit, message_type)
            
            # 检查是否有错误
            if result.get('error'):
                self.logger.warning(f"[获取聊天记录] 查询失败: {result['error']}")
                self.send_json_response({
                    'success': False,
                    'error': result['error']
                }, status_code=404 if result['error'] == '用户不存在' else 500)
                return
            
            # 成功获取数据
            self.logger.info(f"[获取聊天记录] 成功获取聊天记录")
            self.logger.info(f"[获取聊天记录] 候选人: {result.get('candidate', {}).get('name', '未知')}")
            self.logger.info(f"[获取聊天记录] 总消息数: {result.get('total_messages', 0)}")
            self.logger.info(f"[获取聊天记录] AI消息数: {result.get('ai_messages', 0)}")
            self.logger.info(f"[获取聊天记录] 候选人消息数: {result.get('candidate_messages', 0)}")
            
            # 返回数据
            response_data = {
                'success': True,
                'data': result,
                'timestamp': datetime.now().isoformat()
            }
            
            self.logger.info("[获取聊天记录] ========== 请求处理完成 ==========")
            self.logger.info("=" * 80)
            
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"[获取聊天记录] 处理请求失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': f'获取聊天记录失败: {str(e)}'
            }, status_code=500)
    
    def handle_message_dates(self):
        """处理获取消息日期列表请求"""
        try:
            self.logger.info("=" * 80)
            self.logger.info("[消息日期] ========== 开始处理请求 ==========")
            
            # 初始化Monitor（如果还未初始化）
            if EnhancedHTTPRequestHandler.monitor is None:
                self.logger.info("[消息日期] Monitor未初始化，正在初始化...")
                EnhancedHTTPRequestHandler.monitor = N8nMonitor(DB_CONFIG, DEEPSEEK_API_KEY)
                if not EnhancedHTTPRequestHandler.monitor.connect_db():
                    self.logger.error("[消息日期] 数据库连接失败")
                    self.send_json_response({
                        'success': False,
                        'error': '数据库连接失败'
                    }, status_code=500)
                    return
                self.logger.info("[消息日期] Monitor初始化成功")
            
            monitor = EnhancedHTTPRequestHandler.monitor
            
            # 获取消息日期列表
            self.logger.info("[消息日期] 正在查询消息日期列表...")
            dates = monitor.get_message_dates()
            
            self.logger.info(f"[消息日期] 成功获取 {len(dates)} 个日期")
            
            # 返回数据
            response_data = {
                'success': True,
                'dates': dates,
                'total_dates': len(dates),
                'timestamp': datetime.now().isoformat()
            }
            
            self.logger.info("[消息日期] ========== 请求处理完成 ==========")
            self.logger.info("=" * 80)
            
            self.send_json_response(response_data)
            
        except Exception as e:
            self.logger.error(f"[消息日期] 处理请求失败: {str(e)}", exc_info=True)
            self.send_json_response({
                'success': False,
                'error': f'获取消息日期列表失败: {str(e)}'
            }, status_code=500)
    
    def log_message(self, format, *args):
        """重写日志方法，只记录重要信息"""
        if '/api/' in format or '404' in format or '500' in format:
            super().log_message(format, *args)


def start_server():
    """启动HTTP服务器"""
    print("\n" + "=" * 60)
    print("  服务器启动中...")
    print("=" * 60 + "\n")
    
    # 初始化日志系统
    setup_logging()
    logger = logging.getLogger(__name__)
    logger.info("服务器启动中...")
    print("[INFO] 日志系统已初始化")
    
    # 支持通过环境变量指定端口，默认8001
    try:
        base_port = int(os.getenv('PORT', '8001'))
    except ValueError:
        base_port = 8001
    
    print(f"[INFO] 基础端口: {base_port}")
    
    # 切换到项目目录
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    
    # 创建HTTP服务器，若端口占用则尝试下一个端口（最多尝试10个端口）
    Handler = EnhancedHTTPRequestHandler
    
    # 加载保存的提示词
    if Handler.load_saved_prompt('reply_reasonable'):
        print("[INFO] 已加载保存的回复合理评估提示词")
    else:
        print("[INFO] 使用默认的回复合理评估提示词")
    
    httpd = None
    selected_port = None

    for candidate_port in range(base_port, base_port + 10):
        try:
            httpd = socketserver.TCPServer(("", candidate_port), Handler)
            selected_port = candidate_port
            break
        except OSError:
            continue

    if httpd is None:
        print("[ERROR] 未找到可用端口(从 {base} 起连续10个)".format(base=base_port))
        sys.exit(1)

    print(f"✅ 服务器启动在端口 {selected_port}")
    print(f"🌐 访问地址: http://localhost:{selected_port}/index.html")
    
    if API_AVAILABLE:
        print(f"🔌 API端点可用: http://localhost:{selected_port}/api/")
        print("  可用端点:")
        print("    GET  /api/health - 健康检查")
        print("    POST /api/batch-evaluate - 批量评估消息")
        print("    POST /api/save-feedback - 保存用户反馈")
        print("    POST /api/export-evaluations - 导出评估结果")
    else:
        print("⚠️  API端点不可用（Monitor未加载）")
    
    print("\n" + "=" * 60)
    print("  ⚠️  按 Ctrl+C 停止服务器")
    print("=" * 60 + "\n")

    # 延迟2秒后打开浏览器（使用实际端口）
    Timer(2.0, lambda: webbrowser.open(f"http://localhost:{selected_port}/index.html")).start()

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\n服务器已停止")
    finally:
        try:
            httpd.server_close()
        except Exception:
            pass
        sys.exit(0)

if __name__ == '__main__':
    start_server()
